Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to get data from a list but orderly mer mean get in the order, but I have this code is not working out.
if (item is TextBoxUniversal)
{
foreach (string i in itemlist)
{
ItemValorEntity x = new ItemValorEntity();
x.Item_Id = i[itemIndex].ToString();
strItem = x.Item_Id;
itemIndex += 1;
}
txt.Name = item.Name;
txt = GetTexBox(txt.Name, groupBox1);
itemValor.Item_Id = strItem;
itemValor.cClave = Convert.ToString(cboGTTipoItems.SelectedValue);
itemValor.Valor = txt.Text;
}
In a list I have several items can be 101, 102, 103, etc.. I need to get them in order.
That code only managed to get 1 but is not is 1 is 101
Solucionado
if (item is TextBoxUniversal)
{
string _item = itemlist[itemIndex].ToString();
itemIndex++;
txt.Name = item.Name;
txt = GetTexBox(txt.Name, groupBox1);
itemValor.Item_Id = _item;
itemValor.cClave = Convert.ToString(cboGTTipoItems.SelectedValue);
itemValor.Valor = txt.Text;
}
Updated:
I removed previous answer as I believe this is more what you're looking for. The ability to sort a list that you've received. Your question is still poorly asked, so I'm going to go off some assumptions you've implied. Those are:
Utilize a hard-coded List.
Sort the List.
Display to a user.
The class you'll want to look at for the sort is List(T).Sort it provides a clean, quick, and simple approach to accomplish the goal. Details can be found here.
I'm going to use a more practical scenario, we have a series of students that will require their score / grades be sorted before output to our user.
To begin will build our Student object.
public class Student
{
public string Name { get; set; }
public int Score { get; set; }
public string Grade { get; set; }
}
So far our object is pretty simple, it contains:
Name (Who it is)
Actual score (Numeric Representation)
Grade (Letter Representation)
Now we will implement the IComparable<Student> to our Student object. This will implicitly implement the following method:
public int CompareTo(Student other)
{
throw new NotImplementedException();
}
So we will remove the Exception out of the method and implement:
if(other == null)
return 1;
else
return this.Score.CompareTo(other.Score);
This small amount of code will do the following:
If the object is null it will be greater.
It will compare our current Property to our Parameter Value.
Now all we have to do for our implementation:
// Create Our List
List<Student> student = new List<Student>();
// Add our Students to the List
student.Add(new Student() { Name = "Greg", Score = 100, Grade = "A+" });
student.Add(new Student() { Name = "Kelli", Score = 32, Grade = "F" });
student.Add(new Student() { Name = "Jon", Score = 95, Grade = "A" });
student.Add(new Student() { Name = "Tina", Score = 93, Grade = "A-" });
student.Add(new Student() { Name = "Erik", Score = 82, Grade = "B" });
student.Add(new Student() { Name = "Ashley", Score = 75, Grade = "C" });
// Apply our Sort.
student.Sort();
// Loop through Our List:
foreach (Student placement in student)
listBox1.Items.Add(placement.Name + " " + placement.Score + " " + placement.Grade);
That will put them in a Ascending order. You can tweak and configure to make it Descending should you require it, or even more complex. Hopefully this is a nice starting point.
Also some items have OrderBy or OrderByDescending accessible. So you can actually do code like this to a Dictionary.
student.OrderByDescending(s => s.Value);
You have a slew of possibilities, hopefully this gets you started and able to think about your implementation a bit.
Related
I try to build some table inside a text file which
look like this:
Name Grade
--------------------
John 100
Mike 94
...
...
I have this bunch of code:
List<string> NamesList = new List<string>();
List<int> Grades = new List<int>();
Grades.Add(98);
Grades.Add(100);
NamesList.Add("John");
NamesList.Add("Alon");
if (NamesList.Count() == Grades.Count())
{
var length = NamesList.Count();
var min = Grades.Min();
var max = Grades.Max();
using (System.IO.StreamWriter myF =
new System.IO.StreamWriter(#"C:\Users\axcel\textfolder\myFile.txt", true))
{
for (int i = 0; i < length; i++)
{
if (i == 0)
{
myF.WriteLine("Name Age Grade");
myF.WriteLine("==================================");
}
myF.WriteLine(NamesList.ElementAt(i));
myF.WriteLine(" ");
myF.WriteLine(Grades.ElementAt(i));
}
}
}
but my problem is that writing the grades after the names it is writing in a new line. I thought of writing it together to a string and to streaming it but I want to avoid an extra computing...
How can I solve it?
WriteLine() always add a new line after your text. So in your case it should be
myF.Write(NamesList.ElementAt(i));
myF.Write(" ");
myF.WriteLine(Grades.ElementAt(i));
var students = new List<(string name, int age, int grade)>()
{
("John", 21, 98),
("Alon", 45, 100)
};
students.Add(("Alice", 35, 99));
using (var writer = new StreamWriter("myFile.txt"))
{
writer.WriteLine(string.Join("\t", "Name", "Age", "Grade"));
foreach(var student in students)
{
writer.WriteLine(string.Join("\t", student.name, student.age, student.grade));
}
}
As some comments have suggested you could use a Student class to group name, age and grade. In this example I've used a Value Tuple instead.
You can see how it improves the readability of the code and you can focus on the problem you are actually trying to solve. You can reduce your write operation to a simple, readable expression - meaning you are less likely to make mistakes like mixing up Write and WriteLine.
You can always align the text by using string interpolation alignment.
To follow some of the comments, I also urge you to build a class holding the values.
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public int Grade { get; set; }
}
And here is the code using string interpolation alignment
var students = new List<Student>
{
new Student {Name = "John", Age = 10, Grade = 98},
new Student {Name = "Alon", Age = 10, Grade = 100}
};
var minGrade = students.Min(s => s.Grade);
var maxGrade = students.Max(s => s.Grade);
using (var myF = new System.IO.StreamWriter(#"C:\Users\axcel\textfolder\myFile.txt", true))
{
myF.WriteLine($"{"Name",-15}{"Age",-10}{"Grade",5}");
myF.WriteLine("==============================");
foreach (var student in students)
{
myF.WriteLine($"{student.Name,-15}{student.Age,-10}{student.Grade,5}");
}
}
This will produce the following result:
Name Age Grade
==============================
John 10 98
Alon 10 100
Positive numbers are right-aligned and negative numbers are left-aligned
You can read more about it on the string interpolation page at Microsoft Docs
To solve the issue you are having, you could just use:
myF.WriteLine(NamesList.ElementAt(i) + " " + Grades.ElementAt(i));
However the code you provided would benefit from being modified as described in the comments (create a class, use FileHelpers, etc.)
Solution 1:
Why you are not trying the concatenating the two string like:
string line = NamesList.ElementAt(i) + " " + Grades.ElementAt(i);
myF.WriteLine(line);
OR
Solution 2:
What you are using is WriteLine("Text") function which always writes the text to next line. Instead you can use Write("Text") function which will write the string on same line. you can try like:
myF.Write(NamesList.ElementAt(i));
myF.Write(" ");
myF.Write(Grades.ElementAt(i));
myF.WriteLine(); // Here it will enter to new line
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have to parse this string
"Cust =Customer CustCR =Customer Credit Prod=Product SalesRep=Sales Rep TaxCat=Tax Category TaxId=Tax ID VolBill=Volume Billing"
as Code, Description like Code=Cust and Description=Customer
split on basis of space is not working for this because there is also a space in description too .
Instead of splitting on space you can split on the equals sign. Then the code will be the value after the last space of the previous item and the description will be everything up to the last space making sure to trim the spaces that might show up before the equals. And you can replace the Dictionary with whatever data type you want to load the values into. Also you have to handle the first and last values as special cases. Note this will only work if the codes do not contain spaces.
string str = "Cust =Customer CustCR =Customer Credit Prod=Product SalesRep=Sales Rep TaxCat=Tax Category TaxId=Tax ID VolBill=Volume Billing";
var separated = str.Split('=');
string code = separated[0].Trim();
var codeAndDescription = new Dictionary<string, string>();
for (int i = 1; i < separated.Length - 1; i++)
{
int lastSpace = separated[i].Trim().LastIndexOf(' ');
var description = separated[i].Substring(0, lastSpace).Trim();
codeAndDescription.Add(code, description);
code = separated[i].Substring(lastSpace + 1).Trim();
}
codeAndDescription.Add(code, separated[separated.Length - 1]);
foreach (var kvp in codeAndDescription)
Console.WriteLine(kvp);
Outputs
[Cust, Customer]
[CustCR, Customer Credit]
[Prod, Product]
[SalesRep, Sales Rep]
[TaxCat, Tax Category]
[TaxId, Tax ID]
[VolBill, Volume Billing]
A little modification for another case if description is empty, also used custom Item class to store output in a list
class Item {
public string Code { get; set; }
public string Description { get; set; }
}
class Program
{
static void Main(string[] args)
{
string str = "0= 1=Full Time 2=Part Time 3=Seasonal 4=Variable";
var separated = str.Split('=');
string code = separated[0].Trim();
var codeAndDescription = new List<Item>();
foreach (var sep in separated.Skip(1).Take(separated.Length - 2))
{
int lastSpace = sep.Trim().LastIndexOf(' ');
var description = lastSpace != -1 ? sep.Substring(0, lastSpace).Trim(): "" ;
codeAndDescription.Add(new Item { Code=code,Description=description });
code = sep.Substring(lastSpace + 1).Trim();
}
codeAndDescription.Add(new Item { Code = code, Description = separated.Last() });
foreach (var kvp in codeAndDescription)
{
Console.WriteLine("Code={0} Description={1}", kvp.Code, kvp.Description);
}
Console.ReadLine();
}
}
I have this code:
if (currentWeekSaved)
{
DateTime currentWeek = Convert.ToDateTime(comboBoxWeekToSchedule.SelectedValue);
AssignmentHistory ah = AYttFMConstsAndUtils.AssignmentHistList
.FirstOrDefault(i => i.WeekOfAssignment == currentWeek && i.TalkType == BIBLE_READING_TALK_TYPE);
if (ah != null)
{
var assignedStudentFirstname = AYttFMConstsAndUtils.GetStudentFirstNameForID(ah.StudentID_FK);
var assignedStudentLastname = AYttFMConstsAndUtils.GetStudentLastNameForID(ah.StudentID_FK);
assignedStudent = new Student() {FirstName = assignedStudentFirstname, LastName = assignedStudentLastname, StudentID = ah.StudentID_FK};
}
}
List<Student> BRStudents =
AYttFMConstsAndUtils.StudentsList.Where(h => h.EnrolledInAYttFM)
.Where(i => i.RecommendedNextTalkTypeID.Equals(BIBLE_READING_TALK_TYPE))
.OrderBy(j => j.WeekOfLastAssignment)
.ToList();
if (null != assignedStudent)
{
// If exists in list, remove it first, and then add it back at the top
//int assignedStudentIndex = BRStudents.IndexOf(assignedStudent);
int assignedStudentIndex = checkedListBoxBR.Items.IndexOf(assignedStudent.FullName);
if (assignedStudentIndex > -1)
{
BRStudents.RemoveAt(assignedStudentIndex);
}
BRStudents.Insert(0, assignedStudent);
}
checkedListBoxBR.DataSource = BRStudents;
checkedListBoxBR.DisplayMember = "FullName";
checkedListBoxBR.ValueMember = "StudentID";
If there is already someone assigned for the week being processed, I want to first remove them from checkedListBoxBR and then add them back at index 0. However, even when the person is in checkedListBoxBR, this line:
int assignedStudentIndex =
checkedListBoxBR.Items.IndexOf(assignedStudent.FullName);
...fails to find them. The value of "assignedStudent.FullName" does equal the value of one of the items; as seen above, "FullName" is the ValueMember for CheckedListBox:
On stepping through it, the list of students, BRStudents, has 2 members, the person already assigned and another person; "assignedStudent" is the person already assigned; checkedListBoxBR has three items, the person already assigned plus two others.
So why is assignedStudentIndex -1 when the person assigned is represented in FullName? It's true that I don't explicitly assign FullName in this line:
assignedStudent = new Student() {FirstName = assignedStudentFirstname, LastName = assignedStudentLastname, StudentID = ah.StudentID_FK};
...but FullName is a calculated field in the class:
public class Student
{
public int StudentID { get; set; }
. . .
public string FirstName { get; set; }
public string LastName { get; set; }
. . .
public string FullName
{
get
{
return $"{FirstName} {LastName}";
}
set { }
}
}
So why in tarnation is "So and So" not found in the CheckedListBox's items when it is most decidedly there?
UPDATE
Olivier's suggestion seems good ("iterate through checkedListBoxBR.Items and see if you find a match between the item's DisplayMember and the assignedStudent.FullName"). But how? I thought maybe something like this would do it:
for (int i = 0; i < checkedListBoxBR.Items.Count; i++)
{
if checkedListBoxBR.Items[0].DisplayMember.Equals(assignedStudent.FullName)
{
checkedListBoxBR.RemoveAt(i);
}
}
...but "DisplayMember" is not recognized here (nor is "RemoveAt").
UPDATE 2
Responding to Olivier's nudgings, I fixed the above to be:
for (int i = 0; i < checkedListBoxBR.Items.Count; i++)
{
if checkedListBoxBR.Items[i].DisplayMember.Equals(assignedStudent.FullName)
{
checkedListBoxBR.Items.RemoveAt(i);
}
}
...but it still considers DisplayMember to be property-non-grata.
UPDATE 3
I have simplified the code, and it's working pretty well. Here is the simplified version:
// Called whenever the week changes (a new week is navigated to/selected in the combobox)
private void PopulateBibleReadingComboBox()
{
int BIBLE_READING_TALK_TYPE = 1;
Student assignedStudent = null;
List<Student> assignedStudents = null;
// If the week has been saved, get the student who has been assigned the Bible Reading
if (currentWeekSaved)
{
DateTime currentWeek = Convert.ToDateTime(comboBoxWeekToSchedule.SelectedValue);
AssignmentHistory ah = AYttFMConstsAndUtils.AssignmentHistList
.FirstOrDefault(i => i.WeekOfAssignment == currentWeek && i.TalkType == BIBLE_READING_TALK_TYPE);
if (ah != null)
{
var assignedStudentFirstname = AYttFMConstsAndUtils.GetStudentFirstNameForID(ah.StudentID_FK);
var assignedStudentLastname = AYttFMConstsAndUtils.GetStudentLastNameForID(ah.StudentID_FK);
assignedStudent = new Student() {FirstName = assignedStudentFirstname, LastName = assignedStudentLastname, StudentID = ah.StudentID_FK};
// Use the ID to get the student and put him/her in a 1-person list (needed for
// the subsequent LINQ Union)
assignedStudents =
AYttFMConstsAndUtils.StudentsList.Where(i => i.StudentID == ah.StudentID_FK).ToList();
}
}
// Get all the candidates for assignment
List<Student> BRStudents =
AYttFMConstsAndUtils.StudentsList.Where(h => h.EnrolledInAYttFM)
.Where(i => i.RecommendedNextTalkTypeID.Equals(BIBLE_READING_TALK_TYPE))
.OrderBy(j => j.WeekOfLastAssignment)
.ToList();
if (null != assignedStudent)
{
List<Student> allBRStudents = assignedStudents.Union(BRStudents).ToList();
checkedListBoxBR.DataSource = allBRStudents;
checkedListBoxBR.DisplayMember = "FullName";
checkedListBoxBR.ValueMember = "StudentID";
}
else // No assigned student found, bind to the candidate students only
{
checkedListBoxBR.DataSource = BRStudents;
checkedListBoxBR.DisplayMember = "FullName";
checkedListBoxBR.ValueMember = "StudentID";
}
// In either case, highlight and check the first one now
checkedListBoxBR.SelectedIndex = 0;
checkedListBoxBR.SetItemChecked(0, true);
}
I can see two things wrong.
First, you populate checkedListBoxBR after you check for the presence of a certain item.
Secondly, you are comparing apples and oranges. checkedListBoxBR.Items is a Collection of objects, and you are comparing that to a string (assignedStudent.FullName) via indexOf. That will not work.
A better solution would be to iterate through checkedListBoxBR.Items and see if you find a match between the item's DisplayMember and the assignedStudent.FullName.
Or you could use a Student object in the the indexOf call, but then you need to make sure you implement IEquatable, override Equals, GetHashCode, etc.
The items of your checkedListBoxBR are of type Student, because the items in your DataSource are of type Student:
List<Student> BRStudents = [...]
checkedListBoxBR.DataSource = BRStudents;
By using the IndexOf function with a string (Student.FullName) as a parameter, you are comparing many Student objects to one string. No Student is equal to your string so you get the result of -1. Try modifing your code like this:
int assignedStudentIndex = checkedListBoxBR.Items.IndexOf(assignedStudent);
Additionally you might want to override the Equals method.
Edit:
As #olivier-de-meulder correctly pointed out you need to move these lines above your lookup to make any option work:
checkedListBoxBR.DataSource = BRStudents;
checkedListBoxBR.DisplayMember = "FullName";
checkedListBoxBR.ValueMember = "StudentID";
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Im currently making a basic payroll system.
So far I have put all the employee names into a string and an If statement because they all have different hourly rates.
My problem at the moment is linking the same string to the login, so when the employee enters their name and clicks 'login' the program will be able to match the name to the hourly rate when they calculate their weekly hours, tax, pay etc.
Is there a solution/method for this?
string[] employeenames = new string[] { "Jordan", "Ryan", "Dan", };
decimal payRate = 0.0M;
for (int i = 0; i < employeenames.Length; i++)
{
if (employeenames[i] == "Jordan")
{
payRate = 7.20M;
}
else if (employeenames[i] == "Ryan")
{
payRate = 9.47M;
}
else if (employeenames[i] == "Dan")
{
payRate = 13.27M;
}
Although the better option is to use a Database, you can use a switch statement instead.
string loginName = "";
decimal payRate = 0.0 + "M";
switch (loginName){
case "Jordan":
payRate = 7.20 + "M";
break;
case "Ryan":
payRate = 9.47 + "M";
break;
case "Dan":
payRate = 13.27 + "M";
break;
default:
Console.WriteLine("Invalid login name");
break;
}
If you are only using a name to login with, this will be fine. However if you plan on using a password alongside the name, use a database.
So the better way to do this would be to use the following:
Create a class that houses every employee you could want
public class Employee{
public string Name {get;set;}
public double PayRate {get;set;}
}
You can then add employees to a list made out of this class like this:
var employeeList = new List<Employee>();//This list should be populated from the database, below is just proof of concept showing the search syntax
employeeList.Add(new Employee{ Name = "John", PayRate = 33.00});
employeeList.Add(new Employee{ Name = "Steve", PayRate = 2});
employeeList.Add(new Employee{ Name = "Bert", PayRate = 22.99});
The upshot here is you can write a data access method to populate this list from a database.
This will allow you to query against this data in a more meaningful way:
var userLoggedIn = "Steve";
var foundAmmount = employeeList.FirstOrDefault (x => x.Name == userLoggedIn).PayRate;
The above code returns 2.
I have a generic list
How do I remove an item?
EX:
Class Student
{
private number;
public Number
{
get( return number;)
set( number = value;)
}
private name;
public Name
{
get( return name;)
set( name = value;)
}
main()
{
static List<student> = new list<student>();
list.remove...???
}
}
Well, there is nothing to remove because your list is empty (you also didn't give it an identifier, so your code won't compile). You can use the Remove(T item) or RemoveAt(int index) to remove an object or the object at a specified index respectively (once it actually contains something).
Contrived code sample:
void Main(...)
{
var list = new List<Student>();
Student s = new Student(...);
list.Add(s);
list.Remove(s); //removes 's' if it is in the list based on the result of the .Equals method
list.RemoveAt(0); //removes the item at index 0, use the first example if possible/appropriate
}
From your comments I conclude that you read student name from input and you need to remove student with given name.
class Student {
public string Name { get; set; }
public int Number { get; set; }
public Student (string name, int number)
{
Name = name;
Number = number;
}
}
var students = new List<Student> {
new Student ("Daniel", 10),
new Student ("Mike", 20),
new Student ("Ashley", 42)
};
var nameToRemove = Console.ReadLine ();
students.RemoveAll (s => s.Name == nameToRemove); // remove by condition
Note that this will remove all students with given name.
If you need to remove the first student found by name, first use First method to find him, and then call Remove for the instance:
var firstMatch = students.First (s => s.Name == nameToRemove);
students.Remove (firstMatch);
If you want to ensure there is only one student with given name before removing him, use Single in a similar fashion:
var onlyMatch = students.Single (s => s.Name == nameToRemove);
students.Remove (onlyMatch);
Note that Single call fails if there is not exactly one item matching the predicate.
List<Student> students = new List<Student>();
students.Add(new Student {StudentId = 1, StudentName = "Bob",});
students.RemoveAt(0); //Removes the 1st element, will crash if there are no entries
OR to remove a known Student.
//Find a Single Student in the List.
Student s = students.Where(s => s.StudentId == myStudentId).Single();
//Remove that student from the list.
students.Remove(s);
Well, you didn't give your list a name, and some of your syntax is wonky.
void main()
{
static List<Student> studentList = new List<Student>();
}
// later
void deleteFromStudents(Student studentToDelete)
{
studentList.Remove(studentToDelete);
}
There are more remove functions detailed here: C# List Remove Methods
int count=queue.Count;
while(count>0)
{
HttpQueueItem item = queue[0];
/// If post succeeded..
if (snd.IsNotExceedsAcceptedLeadsPerDayLimit(item.DataSaleID, item.AcceptedLeadsPerDayLimit) && snd.PostRecord(item.DataSaleDetailID, item.PostString, item.duplicateCheckHours, item.Username, item.Password, item.successRegex))
{
if (item.WaitTime > 0)
Thread.Sleep(item.WaitTime);
queue.Remove(item);
}
///If Exceeds Accepted leads per day limit by DataSale..
else if (!snd.IsNotExceedsAcceptedLeadsPerDayLimit(item.DataSaleID, item.AcceptedLeadsPerDayLimit))
{
queue.RemoveAll(obj => obj.DataSaleID == item.DataSaleID);
}
/// If Post failed..
else //if (!snd.PostRecord(item.DataSaleDetailID, item.PostString, item.duplicateCheckHours, item.Username, item.Password, item.successRegex))
{
queue.Remove(item);
}
count = queue.Count;
}
To delete a row or record from generic list in grid view, just write this code-
List<Address> people = new List<Address>();
Address t = new Address();
people.RemoveAt(e.RowIndex);
grdShow.EditIndex = -1;
grdShow.DataSource = people;
grdShow.DataBind();
Maybe you can use a Dictionary<string, Student> instead of the List<Student>.
When you add a Student, add its ID or Name or whatever can uniquely identify it. Then you can simply call myStudents.Remove(myStudentId)
Try linq:
var _resultList = list.Where(a=>a.Name != nameToRemove).Select(a=>a);
I made a program that contains 7 cards, then shuffle and I hope to take in order to help them
class Program
{
static void Main(string[] args)
{
Random random = new Random();
var cards = new List<string>();
//CARDS VECRTOR
String[] listas = new String[] { "Card 1", "Card 2", "Card 3", "Card 4", "Card 5", "Card 6", "Card 7"};
for (int i = 0; i<= cards.Count; i++)
{
int number = random.Next(0, 7); //Random number 0--->7
for (int j = 0; j <=6; j++)
{
if (cards.Contains(listas[number])) // NO REPEAT SHUFFLE
{
number = random.Next(0, 7); //AGAIN RANDOM
}
else
{
cards.Add(listas[number]); //ADD CARD
}
}
}
Console.WriteLine(" LIST CARDS");
foreach (var card in cards)
{
Console.Write(card + " ,");
}
Console.WriteLine("Total Cards: "+cards.Count);
//REMOVE
for (int k = 0; k <=6; k++)
{
// salmons.RemoveAt(k);
Console.WriteLine("I take the card: "+cards.ElementAt(k));
cards.RemoveAt(k); //REMOVE CARD
cards.Insert(k,"Card Taken"); //REPLACE INDEX
foreach (var card in cards)
{
Console.Write(card + " " + "\n");
}
}
Console.Read(); //just pause
}
}