使用LINQ扩展将对象添加到嵌套在Dictionary中的List

时间:2016-09-13 07:21:28

标签: c# linq dictionary foreach

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

Dictionary<string, List<IMyObject>> myObjects;

每一对看起来像这样:

{ firstCategory, new List<IMyObject>> }

我现在有List<T>IMyObject

List<IMyObject> myObjectsUnsorted;

我想循环浏览myObjectsUnsorted并添加到正确的List<T>

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

如何在没有循环的情况下执行此操作?例如,使用LINQ扩展方法?此示例中的其他对象是使用.Select()创建的,但在上一个foreach中,这个对象确实很合适。

2 个答案:

答案 0 :(得分:8)

我建议改为使用lookup

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

ILookup<,>被精确设计为“每个键的多个值”字典。除了构造非常简单之外,它还有一个好处,即如果您查找未表示的键,则会返回一个空序列而不是异常。所以你总是只能写:

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

相反:

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

请注意,查找是不可变的,因为您无法在构造后更改其中的项目。 (如果这些项目是可变的引用类型,你当然可以自己修改对象......)这可能是一种祝福或诅咒,具体取决于你的情况......

答案 1 :(得分:2)

你也可以这样使用GroupBy

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