-2

我有一系列这样的对象

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

(A 是父对象并包含 B 子对象的集合)

我想反转这个,以便子对象(B)成为父对象,即

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

任何人都知道正确的 linq 查询来得到这个结果吗?

4

2 回答 2

3

起初,您可以在没有 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>>.

PS:

任何人都知道正确的 linq 查询来得到这个结果吗?

我想没有人知道,但很多人可以弥补 - 这是你首先要做的,那就是尝试。

于 2013-02-13T00:08:53.677 回答
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>>我们开始使用的原始 IGrouping。有趣的是,select 子句是不必要的,因为语言规范允许查询以 group-by 结尾。

此外,如果需要字典而不是 IGrouping,则 ToDictionary 扩展使这变得简单:

Dictionary<string,List<string>> invertedDict = 
    inverted.ToDictionary(i => i.Key, i => i.ToList());
于 2013-02-13T03:39:05.803 回答