2014-01-08 48 views
1

我有一個箱子列表(唯一,與id),並在每個框中有某些項目(唯一的,與id)。 實施例:如何將一列列表轉換爲C#中的字典?

list<box> boxes = new list<boxes>; 

其中,

class box 
{ ... 
    list<item> items = new list<item>; 
    ... 
} 
  • BOX1:ITEM1,ITEM2,...
  • BOX2:ITEM4,ITEM5,...
  • BOX3:...

我需要找到項目詳細信息,給定項目ID。對此我目前做這樣的事情:

foreach (box b in boxes) 
{ 
    foreach (item i in b.items) 
    { 
     if (i.id == searchId) 
      return i; 
    } 
} 

問題是:我該如何將這個列表數據結構轉換爲字典數據結構?

由於我有鑰匙(Id),所以我認爲使用字典會是更好的選擇?

+0

您正在尋找中,或在框項目:

var dictionary = boxes.SelectMany(box => box.items).ToDictionary(item => item.id); 

然後,您可以使用查找值?如果你正在尋找盒子,那麼內部循環是沒有意義的。如果你正在尋找物品,那你爲什麼要提供box id來搜索? –

+0

對不起,編輯我的退貨聲明。我正在尋找箱子 – Flair

+0

@dev_wired中的物品,但是您正在通過箱子ID查找? –

回答

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); 

所以,如果你不想將與搜索之間的項目字典,或者如果你需要執行一次搜索,那麼你可以使用此解決方案。

+3

+1:但是,您應該使用'TryGetValue'來避免雙重查找成本。 – Douglas

+0

@Douglas謝謝,並同意,TryGetValue會更好 –

+1

感謝您給這兩種情況!但是,在我的情況下,所有項目都是唯一的。這似乎是訣竅。 – Flair

2

假設所有項目都是獨一無二的:

item i; 
if (dictionary.TryGetValue(searchID, out i)) 
    return i;