LINQ分组依据为字典对象


161

我试图使用LINQ创建一个Dictionary<string, List<CustomObject>>List<CustomObject>。我可以使用“ var”使它正常工作,但是我不想使用匿名类型。这是我所拥有的

var x = (from CustomObject o in ListOfCustomObjects
      group o by o.PropertyName into t
      select t.ToList());

我也曾经尝试Cast<>()过从LINQ库使用它x,但是由于它是无效的强制转换,我遇到了编译问题。


如果您尝试var x =(从ListOfCustomObjects组的CustomObject o通过o.PropertyName放入t选择t)。ToList();
esastincy 2011年

44
有什么理由需要这样做而不是使用为此目的而设计的ToLookup?
乔恩·斯基特

1
乔恩,能否请您举例说明在这种情况下ToLookup的工作方式?我对LINQ方法不熟悉。
Atari2600 2011年

8
@JonSkeet您真棒!(我的意思是,每个人都已经知道了,但仍然知道。)之所以我不打算使用ToLookup的原因是,直到现在我才听说过它。现在我明白了!
neminem

1
仅出于完整性考虑,使用var不是使用“匿名”类型,而是使用“隐式”类型。匿名类型是由编译器创建的用于处理构造的新类new { thing = "stuff" };。隐式类型是现有的类,var只是在立即分配变量时引用它们的一种简便方法,可以从分配给它的对象的类型中推断出变量类型。您甚至可以隐式键入引用匿名类型的变量,即:var a = new { thing = "stuff" };
Michael Blackburn

Answers:


350
Dictionary<string, List<CustomObject>> myDictionary = ListOfCustomObjects
    .GroupBy(o => o.PropertyName)
    .ToDictionary(g => g.Key, g => g.ToList());

6
除非您需要“ CustomObject”中的属性作为列表值(此答案中未显示),否则值得检查他的代码是否合理Jon Skeet对建议ToLookup()的问题的评论。
肖恩

3
如果需要不可变的结果,这就是这样做的方法。ToLookup是不可变的。
阿米特

1
我的2美分(只是因为它让我挣扎了一个小时:)):按属性分组时,请确保该属性具有价值!否则,Todict方法无法生成密钥(至少对于String-Properties ...):)
dba

.GroupBy(o => o.PropertyName).ToDictionary(g => g.Key, g => g.ToList())这可能是扩展Linq库的一部分。所以我们只需要做.ToDictionary(o=>o.PropertyName)
Jaider

3
@Jaider,已经有这样的功能:只需替换ToDictionary为即可ToLookup
罗伯特·西诺拉兹基

19

我无法评论@Michael Blackburn,但我想您很遗憾,因为在这种情况下,GroupBy并不是必需的。

像这样使用它:

var lookupOfCustomObjects = listOfCustomObjects.ToLookup(o=>o.PropertyName);
var listWithAllCustomObjectsWithPropertyName = lookupOfCustomObjects[propertyName]

此外,与使用GroupBy()。ToDictionary()相比,我看到的执行方式更好。


我正在进行音译,没有以最好的方式回答问题。
迈克尔·布莱克本

1

对于@ atari2600,这就是在lambda语法中使用ToLookup的答案:

var x = listOfCustomObjects
    .GroupBy(o => o.PropertyName)
    .ToLookup(customObject => customObject);

基本上,它使用IGrouping并将其实现给您,成为一个列表的字典,以PropertyName的值作为键。


为什么要投票?这不是准确的答案吗?
迈克尔·布莱克本

1
万一您错过了它,@ RuudvK在他的回答中提到他怀疑该否决票是因为GroupBy是不必要的。ToLookup有一个过载,可以完成工作。
杰夫B

我确实错过了该回复,感谢您给我加标签。有道理,分组在语法上是不必要的,我只是为了使从查询语法到方法语法的过渡更清晰而留了下来。
迈克尔·布莱克本

GroupBy(仅带一个参数的重载)返回IEnumerable <IGrouping <TKey,TSource >>,随后的ToLookup然后将其转换为一个非常复杂的类型,该类型与IDictionary <TKey,IList <TSource >>甚至与ToLookup都不相似返回正确的类型。
xtofs

-1

以下对我有用。

var temp = ctx.Set<DbTable>()
  .GroupBy(g => new { g.id })
  .ToDictionary(d => d.Key.id);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.