使用Linq通过唯一键创建列表

时间:2014-09-28 10:33:47

标签: c# linq

我有一类依赖类型:

class Dependency
{
    public int Source;
    public int Target:
}

给定List<Dependency>列表我会有以下列表(每行是源/目标对):

1, 2
1, 5
2, 1
3, 4
3, 6

是否可以将它们与Linq合并,以便生成以下内容List<Tuple<int,List<int>>

1, [2,5]
2, [1]
3, [4,6]

如果列出了几千个项目的更大列表,那么使用Linq会是执行上述合并的最快方式吗?

2 个答案:

答案 0 :(得分:4)

您可以像这样使用LINQ group by运算符:

var items = new List<Dependency>();
// add your items to list

var result = (from i in items
             group i by i.Source
             into gr
             select new Tuple<int, List<int>>(gr.Key, gr.Select(a => a.Target).ToList())).ToList();

上述查询应该非常快,尽管很难与其他实现同样事物的方法进行比较。我建议在实践中测试 - 编写替代实现并比较性能。

答案 1 :(得分:3)

  

注意: This other answer建议使用C#的group into语法。我的答案显示了类似的内容,即.ToLookup(…)运算符。如果您要问这两者之间有什么区别,请参阅例如:以下问题:ILookup<TKey, TVal> vs. IGrouping<TKey, TVal>

以下解决方案不会产生List<Tuple<int, List<int>>>,我不能说它是否是最快的解决方案,但它可能是最简洁的:

ILookup<int,int> multiMap = dependencies.ToLookup(d => d.Source, d => d.Target);

dependenciesSourceDependency属性(由第一个lambda指定)分组,而不是将完整的Target个对象放入输出中,选择他们的Dictionary<TKey,TValue>值(由第二个可选的lambda指定)。

你得到的是.ToLookup(…) operator,它基本上类似于foreach (IGrouping<int,int> grouping in multiMap) // enumerate over all groups foreach (int target in grouping) // enumerate over all values in one specific group { int source = grouping.Key; // get the key value of the group … } ,除了每个键可以有多个元素(值)。

以下是一个如何迭代这种数据结构中所有值的示例(所谓的ILookup<TKey,TElement>):

{{1}}