简体   繁体   English

如何转换清单 <Tuple<int, int> &gt;到字典 <int, List<int> &gt;?

[英]How to convert List<Tuple<int, int>> to Dictionary<int, List<int>>?

I have duplicate keys with different values and I want to convert it to a dictionary with 1 key and its values. 我有具有不同值的重复键,我想将其转换为具有1个键及其值的字典。

The next example will explain best what I mean: 下一个示例将最好地解释我的意思:

var tup = new List<Tuple<int, int>>();
tup.Add(new Tuple<int, int>(1, 1));
tup.Add(new Tuple<int, int>(1, 2));

var dic = new Dictionary<int, List<int>>();

What is an elegant way to convert the tup to dic? 将tup转换为dic的一种优雅方法是什么?

I managed to do this with foreach but would like to write it in LINQ. 我设法用foreach做到了,但想用LINQ编写。

foreach (var item in tup)
{
    if (dic.ContainsKey(item.Item1))
    {
        dic[item.Item1].Add(item.Item2);
    }
    else
    {
        dic.Add(item.Item1, new List<int> { item.Item2 });
    }
}
var list = tup.GroupBy(x => x.Item1)
              .ToDictionary(
                    x => x.Key, 
                    x => x.Select(y => y.Item2).ToList());

First, we group by GroupBy item 1. This should be obvious enough. 首先,我们将GroupBy项目1分组。这应该很明显。

Then, we call ToDictionary and pass in a keySelector and an elementSelector . 然后,我们调用ToDictionary并传入keySelectorelementSelector They select the key and value respectively, given an IGrouping<int, Tuple<int, int>> . 给定一个IGrouping<int, Tuple<int, int>>它们分别选择键和值。

For reference, this particular overload of ToDictionary is used . 作为参考, 使用了ToDictionary此特定重载

Alternatively, as Iridium has said in the comments, this works as well: 另外,正如铱公司在评论中所说,这同样有效:

var list = tup.GroupBy(x => x.Item1, x => x.Item2)
              .ToDictionary(x => x.Key, x => x.ToList());

This overload of GroupBy allows you to select 2 things! GroupBy这种重载使您可以选择2件事!

You first need to group by the first tuple element in order to find all elements that have the same key in the dictionary. 首先,您需要对第一个元组元素进行分组,以查找字典中具有相同键的所有元素。 And then just collect the second tuple elements and make a list out of it: 然后只收集第二个元组元素并从中列出一个列表:

tup.GroupBy(t => t.Item1)
   .ToDictionary(g => g.Key, g => g.Select(t => t.Item2).ToList());

You can use GroupBy to resolve this problem, like: 您可以使用GroupBy解决此问题,例如:

var tup = new List<Tuple<int, int>>();
tup.Add(new Tuple<int, int>(1, 1));
tup.Add(new Tuple<int, int>(1, 2));

var dic = tup
         .GroupBy(x => x.Item1)
         .ToDictionary(x => x.Key, tuples => tuples.Select(x => x.Item2).ToList());

BTW, in some cases you can use NameValueCollection , but this is not save your target type, for example 顺便说一句,在某些情况下,您可以使用NameValueCollection ,但这不会保存您的目标类型,例如

var nvc = tup.Aggregate(new NameValueCollection(),
  (seed, current) =>
  {
    seed.Add(current.Item1.ToString(), current.Item2.ToString());
    return seed;
  });

foreach (var item in nvc)
{
  Console.WriteLine($"Key = {item} Value = {nvc[item.ToString()]}");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM