【问题标题】:Add objects to a List nested inside a Dictionary using LINQ extensions使用 LINQ 扩展将对象添加到嵌套在字典中的列表
【发布时间】:2017-01-20 17:11:47
【问题描述】:

我有 Dictionary<T, T>,其中包含一个键(代表一个类别),其中一个空的 List<T> 作为值:

Dictionary<string, List<IMyObject>> myObjects;

每一对看起来像这样:

{ firstCategory, new List<IMyObject>> }

我现在有一个 List&lt;T&gt;IMyObject 的:

List<IMyObject> myObjectsUnsorted;

我想遍历myObjectsUnsorted并添加到正确的List&lt;T&gt;

foreach (var myObject in myObjectsUnsorted)
{
    myObjects[myObject.Category].Add(myObject);
}

如何在没有循环的情况下做到这一点?例如使用 LINQ 扩展方法?我在这个例子中的其他对象是用.Select() 创建的,但这并不真正符合最后一个foreach 的要求。

【问题讨论】:

  • 所以你基本上想用一个表达式在一个列表上做一个 for/each(WHERE) ?
  • Dictionary&lt;K, V&gt; 是否已经存在并且您只想追加?如果是这样,我认为没有理由不使用foreach

标签: c# linq dictionary foreach


【解决方案1】:

我建议改用lookup

ILookup<string, IMyObject> lookup = myObjectsUnsorted.ToLookup(t => t.Category);

ILookup&lt;,&gt; 被精确设计为“每个键多个值”的字典。除了构造起来非常简单之外,它还有一个好处是,如果您查找一个未表示的键,您会得到一个空序列而不是异常。所以你可以总是只写:

foreach (var item in lookup[key])
{
    ...
}

相对于:

IList<MyObject> list;
if (dictionary.TryGetValue(key, out list))
{
    foreach (var item in list)
    {
        ...
    }
}

请注意,查找是不可变的,因为您无法在构建后更改其中的项目。 (如果项目是可变引用类型,您当然可以修改对象本身...)这可能是福也可能是祸,取决于您的情况...

【讨论】:

  • 值得一提的是,这会创建一个不可变的数据结构,因此无法像字典解决方案那样进一步添加/删除。
  • 20行变成了1行,非常感谢!现在我终于明白了 ILookup 以及奖金!不可变绝对是个好消息,幸运的是这一次是一种祝福。我在视图中使用这对,所以我只做一个foreach (var item in lookup) { ... },就像我对字典所做的那样。我将键用作您看到的标题。
  • 乔恩,关于祝福或诅咒的最后一句话真是……太棒了!
【解决方案2】:

你也可以像这样使用GroupBy

var dict = myObjectsUnsorted.GroupBy(q => q.Category)
                            .ToDictionary(q => q.Key, w => new List<IMyObject>(w));

【讨论】:

  • @Jon Skeet 的回答很有魅力,但这绝对是将来知道的好消息!谢谢!
  • 我刚刚意识到唯一的区别似乎是.ToLookup() 返回一个ILookup&lt;IGrouping&lt;T, T&gt;&gt;.GroupBy() 返回一个IEnumerable&lt;IGrouping&lt;T, T&gt;&gt;。我说对了吗?
  • @Oskar 在GroupBy 之后还有ToDictionary,它将IEnumerable&lt;IGrouping&lt;T, T&gt;&gt; 更改为Dictionary&lt;T, T&gt;
  • 是的,我注意到了,所以起初我认为这是获得有用的东西的必要条件,但后来我意识到 .GroupBy() 本身就可以正常工作,就像 .ToLookup() :)
猜你喜欢
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
相关资源
最近更新 更多