开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜