LINQ GroupBy on single property

时间:2018-01-11 22:26:19

标签: linq group-by

我只是不了解GroupBy的LINQ非查询语法。

我有一组对象,我想通过单个属性进行分组。在这种情况下,名称

{ Id="1", Name="Bob", Age="23" }
{ Id="2", Name="Sally", Age="41" }
{ Id="3", Name="Bob", Age="73" }
{ Id="4", Name="Bob", Age="34" }

我想最终得到所有唯一名称的集合

{ Name="Bob" }
{ Name="Sally" }

基于一些例子,我看到我认为这将是这样做的方式

var uniqueNameCollection = Persons.GroupBy(x => x.Name).Select(y => y.Key).ToList();

但我最终得到了一个带有一个项目的集合。所以我可能会因为投影而使事情变得复杂化。我试过这个

var uniqueNameCollection = Persons.GroupBy(x => x.Name).ToList();

结果相同。我最终得到了该系列中的一件商品。我在这做错了什么?我只是期待GroupBy Name 属性。

5 个答案:

答案 0 :(得分:2)

LINQ的GroupBy与SQL GROUP BY的工作方式不同。

GroupBy使用序列和函数来查找要作为参数分组的字段,并返回IGrouping个序列,每个Key s的字段值为IEnumerable<IGrouping<TSource>> GroupBy<TSource, TKey>( IEnumerable<TSource> sequence, Func<TSource, TKey> keySelector) { ... } 按组和该组中的元素序列分组。

class Person 
{
    public string Name;  
}

var people = new List<Person> {
    new Person { Name = "Adam" },
    new Person { Name = "Eve" }
}

所以如果你从这样的列表开始:

IEnumerable<IGrouping<Person>> groups = people.GroupBy(person => person.Name);

按名称分组将如下所示

IEnumerable<string> names = groups.Select(group => group.Key);

然后,您可以从每个组中选择密钥,如下所示:

names

Distinct将是截然不同的,因为如果有多个人具有相同的名称,他们将会在同一个群组中,并且只有一个群组具有该名称。

根据您的需要,选择名称然后使用var names = people.Select(p => p.Name).Distinct();

可能会更有效率
import pickle
import os

high_scores_filename = '/home/ubuntu-dev/Desktop/delete/high_scores.dat'

scores = []

# first time you run this, "high_scores.dat" won't exist
#   so we need to check for its existence before we load
#   our "database"
if os.path.exists(high_scores_filename):
    # "with" statements are very handy for opening files.
    with open(high_scores_filename,'rb') as rfp:
        scores = pickle.load(rfp)
    # Notice that there's no "rfp.close()"
    #   ... the "with" clause calls close() automatically!

names = ["mike", "bob", "joe"]

for name in names:
    high_score = name
    print(name)
    scores.append(high_score)

# Now we "sync" our database
with open(high_scores_filename,'wb') as wfp:
    pickle.dump(scores, wfp)

# Re-load our database
with open(high_scores_filename,'rb') as rfp:
    scores = pickle.load(rfp)

print(scores)

答案 1 :(得分:1)

var names = Persons.Select(p => p.Name).Distinct().ToList()

如果你只想要名字

答案 2 :(得分:1)

var uniqueNameCollection = Persons.GroupBy(x => x.Name).Select(y => y.Key).ToList();

似乎对我有效。 .net小提琴显示正确的预期结果:https://dotnetfiddle.net/2hqOvt

答案 3 :(得分:0)

使用您的数据我运行了以下代码语句

var uniqueNameCollection = people.GroupBy(x => x.Name).Select(y => y.Key).ToList();

返回结果是List

  • Bob
  • 萨利

列表中有2个项目 运行以下声明,您的计数应为2。

people.GroupBy(x => x.Name).Select(y => y.Key).ToList().Count();

答案 4 :(得分:0)

为我工作,下载一个金块MoreLinq     使用MoreLinq

var distinctitems = list.DistinctBy( u => u.Name);