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

Osk*_*kar 1 c# linq foreach dictionary

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

Dictionary<string, List<IMyObject>> myObjects;
Run Code Online (Sandbox Code Playgroud)

每一对看起来像这样:

{ firstCategory, new List<IMyObject>> }
Run Code Online (Sandbox Code Playgroud)

我现在有一个List<T>IMyObject"S:

List<IMyObject> myObjectsUnsorted;
Run Code Online (Sandbox Code Playgroud)

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

foreach (var myObject in myObjectsUnsorted)
{
    myObjects[myObject.Category].Add(myObject);
}
Run Code Online (Sandbox Code Playgroud)

如何在没有循环的情况下完成此操作?例如,使用LINQ扩展方法?我在这个例子中创建了其他对象,.Select()但是最后这个对象并不合适foreach.

Jon*_*eet 8

我建议使用查找:

ILookup<string, IMyObject> lookup = myObjectsUnsorted.ToLookup(t => t.Category);
Run Code Online (Sandbox Code Playgroud)

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

foreach (var item in lookup[key])
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

相反:

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

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

  • 值得一提的是,这会创建一个不可变的数据结构,因此不需要像字典解决方案那样进一步添加/删除. (2认同)