我有一系列像这样的对象
A1 - B1, B2, B3
A2 - B1
A3 - B1, B2
(A是父级,包含B子对象的集合)
我想反转它,以便子对象(B)成为父对象,即
B1 - A1, A2, A3
B2 - A1, A3
B3 - A1
任何人都知道正确的linq查询才能得到这个结果吗?
答案 0 :(得分: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
实际反转列表并获取对的顺序,按值分组,而不是键
使用ToDictionary
创建与原始结构相同的结构,即Dictionary<string,List<string>>
。
P.S:
任何人都知道正确的linq查询才能得到这个结果吗?
我想没有人知道,但很多人都可以弥补 - 这就是你首先要做的事情,那就是尝试。
答案 1 :(得分:0)
任何人都知道正确的linq查询才能得到这个结果吗?
LINQ非常直接,紧跟@ Konstantin的回答......
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>
的字符串Key
属性对应dict
中的唯一子级。 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());