Using List<Person> Distinct() to return 2 values
I have a Person
class, with Name
and AreaID
properties.
public class Person
{
public string Name;
public int AreaID;
// snip
}
I have a List<Person>
with the potential for hundreds of Person objects in the list.
e.g., 100 Persons with AreaID = 1 and 100 Persons with AreaID = 2
I want to return disti开发者_开发问答nct list of AreaID's and how many Persons have that AreaID.
For example, AreaID = 1 Persons = 100 AreaID = 2 Persons = 100
Use the GroupBy method.
var list = ...list of Persons...
var areas = list.GroupBy( p => p.AreaID )
.Select( g => new {
AreaID = g.Key,
Count = g.Count()
});
Looks like you want to group by area ID then:
var groups = from person in persons
group 1 by person.AreaID into area
select new { AreaID = area.Key, Persons = area.Count() };
I'm using "group 1" to indicate that I really don't care about the data within each group - only the count and the key.
This is inefficient in that it has to buffer all the results for the sake of grouping - you make well be able to use Reactive LINQ in .NET 4.0 to do this more efficiently, or you could certainly use Push LINQ if you wanted to. Then again, for relatively small datasets it probably doesn't matter :)
Surprisingly nobody advised to override Equals
and GetHashCode
. If you do so you can do folowing:
List<Person> unique = personList.Distinct();
Or even
List<Person> areaGroup = personList.GroupBy(p => p.AreaID);
List<Person> area1Count = personList.Where(p => p.AreaID == 1).Count();
This gives you more flexibility, - no need in useless anonymous class.
return list.GroupBy(p => p.AreaID)
.Select(g => new { AreaID = g.Key, People = g.Count() });
you could use list.GroupBy(x => x.AreaID);
You can try this:
var groups = from person in list
group person by person.AreaID into areaGroup
select new {
AreaID = areaGroup.Key,
Count = areaGroup.Count()
};
var people = new List<Person>();
var q = from p in people
group p by p.AreaId into g
select new { Id = g.Key, Total = g.Count() };
people.Add(new Person { AreaId = 1, Name = "Alex" });
people.Add(new Person { AreaId = 1, Name = "Alex" });
people.Add(new Person { AreaId = 2, Name = "Alex" });
people.Add(new Person { AreaId = 3, Name = "Alex" });
people.Add(new Person { AreaId = 3, Name = "Alex" });
people.Add(new Person { AreaId = 4, Name = "Alex" });
people.Add(new Person { AreaId = 2, Name = "Alex" });
people.Add(new Person { AreaId = 4, Name = "Alex" });
people.Add(new Person { AreaId = 1, Name = "Alex" });
foreach (var item in q)
{
Console.WriteLine("AreaId: {0}, Total: {1}",item.Id,item.Total);
}
Something like this, perhaps ?
List<Person> persons = new List<Person> ();
persons.Add (new Person (1, "test1"));
persons.Add (new Person (1, "test2"));
persons.Add (new Person (2, "test3"));
var results =
persons.GroupBy (p => p.AreaId);
foreach( var r in results )
{
Console.WriteLine (String.Format ("Area Id: {0} - Number of members: {1}", r.Key, r.Count ()));
}
Console.ReadLine ();
Instead of distinct, use GroupBy, or the more succinct LINQ statement:
var results = from p in PersonList
group p by p.AreaID into g
select new { AreaID=g.Key, Count=g.Count() };
foreach(var item in results)
Console.WriteLine("There were {0} items in Area {1}", item.Count, item.AreaID);
ToLookup()
will do what you want.
精彩评论