我有一个框列表(唯一,带有id),每个框中都有某些项目(唯一的,带有id)。 示例:
list<box> boxes = new list<boxes>;
其中,
class box
{ ...
list<item> items = new list<item>;
...
}
我需要找到项目详细信息,给定项目ID。为此我现在做这样的事情:
foreach (box b in boxes)
{
foreach (item i in b.items)
{
if (i.id == searchId)
return i;
}
}
问题是:如何将此列表数据结构转换为字典数据结构?
由于我有密钥(Id),所以我认为使用字典会是更好的选择吗?
答案 0 :(得分:5)
如果多个框中可能存在相同的项目,您可以选择所有项目,并按ID分组,然后从每个组中选择第一项作为字典值:
Dictionary<int, item> items = boxes.SelectMany(b => b.items)
.GroupBy(i => i.id)
.ToDictionary(g => g.Key, g.First());
如果所有项目都有唯一ID:
var items = boxes.SelectMany(b => b.items) .
.ToDictionary(i => i.id);
获取项目将如下所示:
if (items.ContainsKey(searchId))
return items[searchId];
正如@Douglas所说,为了避免双重查找,最好使用TryGetValue方法:
item i;
if (items.TryGetValue(searchId, out i))
return i;
注意:没有字典的Linq替代品(它与您的代码完全相同 - 为每次搜索枚举框及其项目):
var item = boxes.SelectMany(b => b.items).FirstOrDefault(i => i.id == searchId);
因此,如果您不想在搜索之间保留带有项目的字典,或者您需要执行单个搜索,那么您可以使用此解决方案。
答案 1 :(得分:2)
假设您的所有商品都是唯一的:
var dictionary = boxes.SelectMany(box => box.items).ToDictionary(item => item.id);
然后您可以使用以下方式查找值:
item i;
if (dictionary.TryGetValue(searchID, out i))
return i;