total value not displaying after looping - c#

ok so i dont know if im missing something?Basically im making a small program using a collection of spongeob charcters, with a class i made called Person. then trying to loop using a foreach and adding the ages. but for some reason it wont display them. heres my code:
List<Person> people = new List<Person>();
people.Add(new Person(80, "Eugene", "Krabs", "11/30/1942"));
people.Add(new Person(59, "Sheldon", "Plankton", "11/30/1942"));
people.Add(new Person(30, "Spongebob", "Squarepants", "06/17/1986"));
people.Add(new Person(43, "Squidward", "Tentacles", "10/9/1977"));
people.Add(new Person(38, "Patrick", "Star", "06/19/1984"));
people.Add(new Person(37, "Sandy", "Cheeks", "11/19/1977"));
foreach(Person p in people)
{
Console.WriteLine(p.DisplayPerson());
}
Console.WriteLine("\n Adding Brandon Isaac to List __________________________________________________________________________________________");
people.Insert (0,new Person(24, "Brandon", "Isaac", "03/24/1998"));
foreach (Person pe in people)
{
Console.WriteLine(pe.DisplayPerson());
}
int tot = 0;
foreach(Person per in people)
{
tot += per.Age;
}
Console.WriteLine("\ntotal of ages in list: ", tot);
everything runs fine except that, the total is 311 after setting my breakpoint on it but it won't display the actual value. Nor does it give me any errors

It looks like you just forgot the format placeholder in your string?:
Console.WriteLine("\ntotal of ages in list: {0}", tot);
Alternatively you can format the string directly instead of as an overload of WriteLine:
Console.WriteLine($"\ntotal of ages in list: {tot}");

As David said, yes you were missing the string format/the proper interpolation syntax
As a bonus, here is how to do it in-line using LINQ
Console.WriteLine($"\ntotal of ages in list: {people.Sum(p => p.Age)}");
Here you use a lambda selector which essentially says for every Person p take their Age property and sum it. The lambda in a sense defines what to take from each iterable element of the collection. Here are some nice examples to get familiar with use of .Sum()

Related

Is there anyway to sort a list based on difference of its two values?

So I have a list, _students, of object type Student and each Student object has a list, Courses , of object type Course. Each course object has two fields "Total no. of lectures" and "No. of lectures attended by the student". I want to sort this list with student objects by the difference of the two properties so guys who have taken all the courses would be at 0 index of the list.
I tried using something like this, but doesnt work.
_students.ForEach(c => c.Courses.OrderBy(le => le.Total - le.Attended))
I think you could do it this way :
List<Student> students = new List<Student>();
students.Sort(delegate(Student s1, Student s2) {
int s1remainingLectures = 0;
int s2remainingLectures = 0;
foreach(Course c in s1.Courses) s1remainingLectures += c.total - c.Attended ;
foreach(Course c in s2.Courses) s2remainingLectures += c.total - c.Attended ;
return s1remainingLectures.CompareTo(s2remainingLectures); });
Implement IComparable on Course.
Here is a generic sample from another question:
public class BankAccount : IComparable<BankAccount>
{
[...]
public int CompareTo(BankAccount that)
{
return this.Balance.CompareTo(that.Balance);
}
}
You can put your own logic inside the CompareTo function.
Actually in your query you are looping inside the students list and order the courses they have.
If I understand you very well I think you're trying to do something like this:
var orderedStudents=_students.ForEach(c => c.Courses.OrderBy(le => le.Total - le.Attended)).ToList();

Changing List Value in C # Also Changes Your Copy Element

I have a list of objects, and I'm passing them by parameter to a function. I want to edit it with some different values! because when I change an item from my list p does it change from the Pessons list, too? it's like accessing the same memory location, but I just want to replicate the list and alter it without causing changes to the other list.
public void GerarPorLider(List<Person> Persons)
{
List<Person> p = Persons;
p[0].Amount += 10;
}
The output that is happening when I execute this code
Persons[0].Amount = 17; p[0].Amount = 17;
The way I expected it
Persons[0].Amount = 7; p[0].Amount = 17;
How can I do this?
This line
List<Person> p = Persons;
does not copy Persons list, it creates an alias for it. Any modification you make to p is actually a modification to Persons list, just by a different alias.
Moreover, Person objects inside the list would need to be copied, too.
Assuming that there is a constructor of Person that takes Person to copy, use this approach:
List<Person> p = Persons.Select(x => new Person(x)).ToList();
If Person does not have a copy constructor, copy it one property at a time:
List<Person> p = Persons.Select(x => new Person {
// I am making up the properties of `Person` to be copied;
// you need to use the actual ones.
Name = x.Name
, LastName = x.LastName
, Address = x.Address
}).ToList();

Searching in ListArray C#

What is the fastest method for searching data from list array in C#?
My code:
public class fruits
{
public string Initial;
public string Fruit;
public fruits(string initials, string names)
{
Initial = initials;
Fruit = names;
}
}
// load
List<fruits> List = new List<fruits>();
List.Add(new fruits("A", "Apple"));
List.Add(new fruits("P", "Pineapple"));
List.Add(new fruits("AP", "Apple Pineapple"));
//combo box select text
var text = combobox.SelectText();
for (int i=0; i<list.Count(); i++)
{
if (list[i].Fruit == text)
{
MessageBox.Show(list[i].Initial);
}
}
I know this search method is not good, if list data contains too much data.
If you want a "fast" solution, you should use a foreach instead of LINQ. This solution can improve your perfomance a lot:
fruits firstOrDefault = null:
foreach (fruits f in List)
{
if (f.Fruit == text)
{
FirstOrDefault = f;
break;
}
}
You can get few more information about the LINQ performance in posts like
Is a LINQ statement faster than a 'foreach' loop?
http://geekswithblogs.net/BlackRabbitCoder/archive/2010/04/23/c-linq-vs-foreach---round-1.aspx
https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/
You can use linq
var result = List.FirstOrDefault(q => q.Fruit == text );
MessageBox.Show(result.Initial);
The best (and only) way to tell what method is fastest for a certain situation is to actually benchmark/measure it with different algorithms. You already have two answers/approaches here (LINQ and foreach). Time both of them and then pick the faster one.
Or in other words: Measuring your code gives you an advantage over those people who think they are too smart to measure. ;)
To speed things up further you might want to consider to keep the list sorted and then do a binary search on the list. It increases the time for insertion, because you have to sort the list after inserts, but it should speed up the search process. But then again: Do not just take my word for it, measure it!

iterating over a collection and removing ones I dont want

I have a problem with the following. I have a collection:
Collection<Vehicle> list = new Collection<Vehicle>();
code = 1,2,3, Description = "aaa"
code = 10,438,13, Description = "bbb"
code = 81,8623,362, Description = "ccc"
code = 163,4312,53, Description = "ddd"
...
But I only care about some of them.. The list I care about is here, i.e. codesCareAbout = "1|2|3|163|4312|53"
I need to iterate through the collection and either deleting the Vehicle I don't care about, or cherry picking into another list containing the Vehicles I care about?
Any suggestions?
Many thanks,
James
You can iterate your list backwards, and use RemoveAt using the for index to remove from the list:
for (int i = list.Count - 1; i >= 0; i--)
{
Foo item = list[i];
if (IsFoobar(item))
list.RemoveAt(i);
}
Counting backwards is required so that you don't mutate your index counting as you go, using a for loop is required because you cannot mutate a list being enumerated with an enumerator.
Alternatively, do as you suggested, populate into an empty list the stuff you want - however, usage depends on whether you need to modify the list you are given or can make a new list.
Assuming that Vehicule has Code (string) property and Description property (question is not clear !).
1/ Clone the list : var clone = list.ToList();
2/ Iterate and decide if current item is interesting :
foreach(var item in clone)
{
if (! IsInteresting(item))
list.Remove(item);
}
3/ IsInteresting could be, for example :
foreach(var code in item.Code.Split(','))
{
if (codesCareAbout.Split('|').Contains(code))
return true;
}
Filtering the list with linq produces the cleanest code:
var interestinglist = list.Where(v=> v.IsInteresting(v));
IsInteresting can be implemented as
codesIcareAbout.Intersect(v.Codes).Any();
this assumes both fields are collections rather than strings, but that is easily fixed with a call to string.Split().

Parse and pivot student assignment data in c#

I've got a list of student/assignment pairs coming in to my application via flat file into a List object and I'd like to validate those assignment names against a list of assignments I have to see which student has done what assignment (if any).
So - I have a list of students, a list of student/assignment pairs, and a list of assignments.
I want to create output like the following:
1. (Heading) -- Student Name -- Assignent One -- Assignment TWo
2. (Detail) -- John Smith -- <complete> -- <complete>
How can I accomplish this?
What I have so far:
// HACCStudentBlogs stores the list of students in a dictionary I've been appending to the key's value with every found blog (crude, I know)
//
Dictionary<string, string> studentBlogs = new Dictionary<string, string>();
foreach (JObject o in root)
{
createDate = (string)o["createdDate"];
studentName = (string)d[(string)o["contributorName"]];
submittedStudents.Add(studentName);
title=(string)o["title"];
if (HACCstudentBlogs.ContainsKey(studentName))
{
HACCstudentBlogs[studentName] += "\t" + title.ToUpper();
}
else
{
}
}
Since you want one row per student, it's easiest to loop over the list of students and do something for each student.
In this case, "something" means that we need to assemble a line of output.
Each line of output is going to have the student's information, and then needs a piece for each assignment. So inside the loop over the students, there will be a loop over the assignments.
In the loop over the assignments, we need to look up and see if we have a pair for that student and assignment. If so, we spit out "complete." Otherwise, "incomplete."
So a plausible way to structure the program would be something like this:
// print some header information
foreach (var student in studentList)
{
Display(student.Name);
foreach (var assignment in assignmentList)
{
if (Exists(student, assignment, studentAssignmentPairs))
Display("<complete>");
else
Display("<incomplete>");
}
// newline
}
with some added flair for formatting it nicely.
Enough to get started?
we really need to know what the list object looks like
but using foreach over a Linq .Distint() woudld be a good startng point

Categories