使用Linq通过唯一键创建列表
本文关键字:一键 创建 列表 唯一 Linq 使用 | 更新日期: 2023-09-27 18:24:45
我有一个类型为Dependency:的类
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是执行上述合并的最快方法吗?
您可以按如下运算符使用LINQ组:
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();
上面的查询应该很快,尽管很难与其他实现相同功能的方法进行比较。我建议在实践中测试这一点——编写替代实现并比较性能。
注意:另一个答案推荐C#的
group into
语法。我的回答显示了类似的东西,即.ToLookup(…)
运算符。如果你在问这两者之间的区别,请参见以下问题:ILookup<TKey、TVal>与IGrouping<TKey,TVal>
下面的解决方案不会产生List<Tuple<int, List<int>>>
,我不能说它是否是最快的解决方案,但它可能是最简洁的:
ILookup<int,int> multiMap = dependencies.ToLookup(d => d.Source, d => d.Target);
.ToLookup(…)
操作符根据Source
属性(如第一个lambda指定的)对dependencies
进行分组,并且它不会将完整的Dependency
对象放入输出中,而是只选择它们的Target
值(如第二个可选lambda指定)。
您得到的是ILookup<TKey,TElement>
,它本质上类似于Dictionary<TKey,TValue>
,只是每个键可以有几个元素(值)。
下面是一个如何在这样的数据结构(所谓的多映射)中迭代所有值的示例:
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
…
}