通过分组在列表上创建字典


106

我在列表中有以下对象:

public class DemoClass
{
    public int GroupKey { get; set; }
    public string DemoString { get; set; }
    public object SomeOtherProperty { get; set; }
}

现在,我要从中创建以下字典:

Dictionary<int, List<DemoClass>>

我想List<DemoClass>按属性将分组GroupKey,但我不知道该如何完成以及是否有帮助。

经过一番思考,我通过以下方式实现了所需的行为:

var groupedDemoClasses = from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                            group demoClass by demoClass.GroupKey
                            into groupedDemoClass
                            select groupedDemoClass;
var neededDictionary = groupedDemoClass.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

但是,有没有办法使它成为单个语句?

Answers:


88
var groupedDemoClasses = (from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                          group demoClass by demoClass.GroupKey
                          into groupedDemoClass
                          select groupedDemoClass).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

这将工作!


198

只是为了使mquander的建议具体化:

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .GroupBy(x => x.GroupKey)
                             .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

当然,如果您也使用较短的变量名,则会使其更短:)

但是,我是否可以建议使用“ 查找”更为合适?Lookup本质上是一个从键到键的字典IEnumerable<T>-除非您真的需要这些值作为列表,否则使用ToLookup调用可以使代码更短(更有效):

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .ToLookup(x => x.GroupKey);

1
我认为在长期环境中,与内置词典相比,查找的性能不佳,因为它会为每个请求建立新的结果...如果我错了,请纠正我!
Andreas Niedermair,2009年

不,它会创建整个查找。通常,ToXXX不使用延迟执行。
乔恩·斯基特

1
(您可能正在考虑进行分组,而分组确实已延迟。)
Jon Skeet

1
如果我不是那么凶恶的话,我会投票给你。来到了Linq,留下来了我从未听说过的数据结构!
克里斯·麦考尔

2
@sasikt:该模型是您可以查找任何内容,如果键不存在,则只会得到一个空集合。这通常比IMO的TryGetValue方法更有用。
乔恩·斯基特

6

您已经将它变成了单线。只需将放在ToDictionary第一行的末尾。如果希望它更短,请使用功能组合语法而不是查询语法。


3

我在这里略微偏离主题,但是由于我一直在寻找一种在Linq中创建字典词典的方法,因此进入了这个话题,而这里的对话使我找到了答案...

可以使用linq创建多级字典,这对于您要搜索多个键或维度的情况很有用。技巧是创建一个分组,然后将其转换为字典,如下所示:

  Dim qry = (From acs In ActualSales _
             Group By acs.ProductID Into Group _
             Select ProductID, Months = Group.ToDictionary(Function(c) c.Period) _
            ).ToDictionary(Function(c) c.ProductID)

结果查询可以按如下方式使用:

 If qry.ContainsKey(_ProductID) Then
      With qry(_ProductID)
          If .Months.ContainsKey(_Period) Then
             ...
          End If
      End With
 End If

希望这对需要这种查询的其他人有所帮助。

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.