2013-02-12 73 views
-3

我有對象的這樣LINQ的反轉父母子女序列

A1 - B1, B2, B3 
A2 - B1 
A3 - B1, B2 

序列(A是父母所含的B子對象的集合)

我要反轉這使孩子對象(B)成爲父項,即

B1 - A1, A2, A3 
B2 - A1, A3 
B3 - A1 

任何人都知道正確的linq查詢來得到這個結果?

回答

1

起初,你可以用自己的雙手輕鬆無LINQ做到這一點:

//init original dictionary 
var dict = new Dictionary<string, List<string>> 
{ 
    {"A1",new List<string> { "B1", "B2", "B3" }}, 
    {"A2",new List<string> { "B1" }}, 
    {"A3",new List<string> { "B1", "B2"}}, 
}; 
//do the task 
var newdict = new Dictionary<string, List<string>>(); 
foreach (var p in dict) 
{ 
    foreach (string s in p.Value) 
    { 
     if (!newdict.ContainsKey(s)) 
      newdict[s] = new List<string>(); 
     newdict[s].Add(p.Key); 
    } 
} 
//see what we've got 
foreach (var p in newdict) 
{ 
    Console.WriteLine(p.Key); 
    foreach (string s in p.Value) 
    { 
     Console.Write(s + "\t"); 
    } 
    Console.WriteLine(); 
} 
Console.ReadLine(); 

其次,LINQ還可以做的工作:

var result = dict.SelectMany(p => p.Value 
            .Select(s => new 
            { 
             Key = p.Key, 
             Value = s 
            })) 
        .GroupBy(a => a.Value) 
        .ToDictionary(g => g.Key, 
            g => g.Select(a => a.Key) 
             .ToList()); 

,我

  • 使用SelectMany來獲取匿名對象的序列,表示密鑰的對和來自第Ë原值List<string>

  • 使用GroupBy真正反轉列表,並獲得對的sequense,由值,而不是鑰匙

  • 使用ToDictionary創建相同的結構,原來,即Dictionary<string,List<string>>分組。

P.S:

任何人都知道正確的LINQ查詢得到這個結果呢?

我想沒有人知道,但許多人都知道,這是你必須做的第一件事,那就是嘗試。

+0

好吧,我應該已經張貼了我有,但是沒有工作。我錯過的部分是SelectMany中的.Select。謝謝。 – user380689 2013-02-13 00:29:07

+0

@ user380689嘗試通過Jon Skeet閱讀[編寫完美問題](http://msmvps.com/blogs/jon_skeet/archive/2010/08/29/writing-the-perfect-question.aspx)。在SO等網站上撰寫問題時,本文確實指出了所有需要記住的事項。遵循所有這些建議可能有助於避免將來的誤解。我很高興我的答案幫助你.. – horgh 2013-02-13 00:40:11

+0

當問題域需要一個多值字典時,你可能會考慮使用ToLookup而不是ToDictionary。 – 2013-02-13 01:38:20

0

任何人都知道正確的linq查詢來得到這個結果嗎?

的LINQ是相當簡單的,並密切關注@康斯坦丁的答案...

var dict = new Dictionary<string, List<string>> 
{ 
    {"A1",new List<string> { "B1", "B2", "B3" }}, 
    {"A2",new List<string> { "B1" }}, 
    {"A3",new List<string> { "B1", "B2"}}, 
}; 

IEnumerable<IGrouping<string,string>> inverted = 
    from kvp in dict 
    from child in kvp.Value 
    group kvp.Key by child; 

IGrouping<string,string>具有對應於從dict獨特的子字符串Key屬性。 IGrouping<string,string>IEnumerable<string>,在這種情況下是父母請求的。換句話說,這個IGrouping很像我們開始的原始Dictionary<string,List<string>>。有趣的是,select語句是不必要的,因爲語言規範允許查詢以group-by結尾。

此外,如果字典需要一個IGrouping的相反,ToDictionary延伸,使這個簡單的:

Dictionary<string,List<string>> invertedDict = 
    inverted.ToDictionary(i => i.Key, i => i.ToList());