C# 使用列表<;人>;Distinct()返回2个值

C# 使用列表<;人>;Distinct()返回2个值,c#,.net,linq,c#-3.0,ienumerable,C#,.net,Linq,C# 3.0,Ienumerable,我有一个Person类,具有Name和AreaID属性 public class Person { public string Name; public int AreaID; // snip } 我有一个列表,列表中可能有数百个Person对象。 e、 例如,100名AreaID=1的人员和100名AreaID=2的人员 我想返回不同的AreaID列表以及有多少人拥有该AreaID 比如说,, AreaID=1人=100人 AreaID=2个人=100看起来您想按区域ID

我有一个
Person
类,具有
Name
AreaID
属性

public class Person
{
   public string Name;
   public int AreaID;

   // snip
}
我有一个
列表
,列表中可能有数百个Person对象。 e、 例如,100名AreaID=1的人员和100名AreaID=2的人员

我想返回不同的AreaID列表以及有多少人拥有该AreaID

比如说,, AreaID=1人=100人
AreaID=2个人=100

看起来您想按区域ID分组,然后:

var groups = from person in persons
             group 1 by person.AreaID into area
             select new { AreaID = area.Key, Persons = area.Count() };
我用“group1”表示我真的不关心每个组中的数据,只关心计数和键


这是低效的,因为为了分组,它必须缓冲所有结果-您最好能够使用.NET4.0中的反应式LINQ来更有效地完成这项工作,或者如果您愿意,您当然可以使用。同样,对于相对较小的数据集,这可能无关紧要:)

使用GroupBy方法

var list = ...list of Persons...

var areas = list.GroupBy( p => p.AreaID )
                .Select( g => new {
                    AreaID = g.Key,
                    Count = g.Count()
                 });
使用或更简洁的LINQ语句,而不是distinct语句:

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);

您可以使用
list.GroupBy(x=>x.AreaID)

您可以尝试以下方法:

var groups = from person in list
             group person by person.AreaID into areaGroup
             select new {
                 AreaID = areaGroup.Key,
                 Count = areaGroup.Count()
             };
var people=newlist();
var q=人的p值
按p区域ID将p分组为g
选择新{Id=g.Key,Total=g.Count()};
添加(新人物{AreaId=1,Name=“Alex”});
添加(新人物{AreaId=1,Name=“Alex”});
添加(新人物{AreaId=2,Name=“Alex”});
添加(新人物{AreaId=3,Name=“Alex”});
添加(新人物{AreaId=3,Name=“Alex”});
添加(新的人物{AreaId=4,Name=“Alex”});
添加(新人物{AreaId=2,Name=“Alex”});
添加(新的人物{AreaId=4,Name=“Alex”});
添加(新人物{AreaId=1,Name=“Alex”});
foreach(q中的var项目)
{
WriteLine(“AreaId:{0},Total:{1}”,item.Id,item.Total);
}

也许是这样的吧

            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 ();
List persons=新列表();
新增(新人员(1,“测试1”);
新增(新人员(1,“测试2”);
新增(新人员(2,“测试3”);
风险值结果=
persons.GroupBy(p=>p.AreaId);
foreach(结果中的var r)
{
Console.WriteLine(String.Format(“区域Id:{0}-成员数:{1}”,r.Key,r.Count());
}
Console.ReadLine();

ToLookup()
会做你想做的事。

令人惊讶的是,没有人建议覆盖
等于
GetHashCode
。如果您这样做,您可以执行以下操作:

 List<Person> unique = personList.Distinct();
List unique=personList.Distinct();
甚至

 List<Person> areaGroup = personList.GroupBy(p => p.AreaID);
 List<Person> area1Count = personList.Where(p => p.AreaID == 1).Count();
List-areaGroup=personList.GroupBy(p=>p.AreaID);
列出area1Count=personList.Where(p=>p.AreaID==1.Count();

这给了你更多的灵活性,-不需要无用的匿名类。

如果你按AreaID分组,键不是已经是AreaID了吗,所以你想要
g.key
而不是
g.key.AreaID
?啊,是的--我重复了我最近使用的一个模式,我有一个复合键,需要使用键的属性。我会解决的,“组n”部分的“n”是什么?也许你应该试试分组结构。我很惊讶还没有人提到这一点;)在第一组中,我的观点是正确的。不过,考虑到它使用person.AreaID进行分组,这对实际性能有很大影响吗?@Reed:这意味着如果您从磁盘流式传输person,那么它就可以更早地进行垃圾收集。但在大多数情况下,这不是一个问题。
 List<Person> unique = personList.Distinct();
 List<Person> areaGroup = personList.GroupBy(p => p.AreaID);
 List<Person> area1Count = personList.Where(p => p.AreaID == 1).Count();