如何在C#中将列表列表转换为字典?

Fla*_*air 1 c# dictionary

我有一个盒子列表(唯一的,带有id),每个盒子里都有一些物品(唯一的,有id).例:

list<box> boxes = new list<boxes>;
Run Code Online (Sandbox Code Playgroud)

哪里,

class box
{   ...
    list<item> items = new list<item>;
    ...
}
Run Code Online (Sandbox Code Playgroud)
  • 方框1:第1项,第2项,......
  • 方框2:第4项,第5项,......
  • 方框3:......

鉴于商品ID,我需要找到商品详情.为此我现在做这样的事情:

foreach (box b in boxes)
{
    foreach (item i in b.items)
    {
        if (i.id == searchId)
            return i;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是:如何将此列表数据结构转换为字典数据结构?

因为我有密钥(Id),所以我认为使用字典会是更好的选择吗?

Ser*_*kiy 5

如果可能在多个框中存在相同的项目,则可以选择所有项目,并按ID分组,然后从每个组中选择第一项作为字典的值:

Dictionary<int, item> items = boxes.SelectMany(b => b.items)
                                   .GroupBy(i => i.id)
                                   .ToDictionary(g => g.Key, g.First());
Run Code Online (Sandbox Code Playgroud)

如果所有项目都具有唯一ID:

var items = boxes.SelectMany(b => b.items)                     .
                 .ToDictionary(i => i.id);
Run Code Online (Sandbox Code Playgroud)

获取项目将如下所示:

if (items.ContainsKey(searchId))
    return items[searchId];
Run Code Online (Sandbox Code Playgroud)

正如@Douglas所说,为了避免双重查找,最好使用TryGetValue方法:

item i;
if (items.TryGetValue(searchId, out i))
    return i;
Run Code Online (Sandbox Code Playgroud)

注意:没有字典的Linq替代方案(它与您的代码完全相同 - 为每次搜索枚举框及其项目):

var item = boxes.SelectMany(b => b.items).FirstOrDefault(i => i.id == searchId);
Run Code Online (Sandbox Code Playgroud)

因此,如果您不想在搜索之间保留包含项目的字典,或者您需要执行单个搜索,那么您可以使用此解决方案.

  • +1:但是,您应该使用`TryGetValue`来避免双重查找成本. (3认同)