2013-02-12 100 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());