使用 LINQ 获取列表中的所有对
Posted
技术标签:
【中文标题】使用 LINQ 获取列表中的所有对【英文标题】:Get all pairs in a list using LINQ 【发布时间】:2021-05-22 04:25:19 【问题描述】:如何获得列表中所有可能的项目对(顺序不相关)?
例如如果我有
var list = 1, 2, 3, 4 ;
我想得到这些元组:
var pairs =
new Tuple(1, 2), new Tuple(1, 3), new Tuple(1, 4),
new Tuple(2, 3), new Tuple(2, 4)
new Tuple(3, 4)
【问题讨论】:
1, 1, 1, 1
列表的期望输出是什么?六个(1, 1)
还是一个(1, 1)
?
【参考方案1】:
对 cgeers 答案稍作重新表述,以获得所需的元组而不是数组:
var combinations = from item1 in list
from item2 in list
where item1 < item2
select Tuple.Create(item1, item2);
(如果需要,请使用 ToList
或 ToArray
。)
以非查询表达式形式(稍微重新排序):
var combinations = list.SelectMany(x => list, (x, y) => Tuple.Create(x, y))
.Where(tuple => tuple.Item1 < tuple.Item2);
这两个实际上都会考虑 n2 个值而不是 n2/2 个值,尽管它们最终会得到正确的答案。另一种选择是:
var combinations = list.SelectMany((x, i) => list.Skip(i + 1), (x, y) => Tuple.Create(x, y));
...但这使用了Skip
,可能也没有被优化。老实说,这可能无关紧要 - 我会选择最适合您使用的那个。
【讨论】:
Jon,这将创建Tuple (1,1)
,它不是一对。
谢谢,这是最好的解决方案。 (但是,你的意思是Skip(x.index + 1)
?)
是的,Except(..)
是不必要的,因为 where
子句负责处理。【参考方案2】:
计算笛卡尔积以确定所有可能的组合。
例如:
var combinations = from item in list
from item2 in list
where item < item2
select new[] item, item2 ;
您可以在此处找到有关使用 LINQ 计算笛卡尔积的更多信息:
http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
然后您可以将其转换为 Tuple 对象的集合。
var pairs = new List<Tuple<int, int>>();
foreach (var pair in combinations)
var tuple = new Tuple<int, int>(pair[0], pair[1]);
pairs.Add(tuple);
简而言之:
var combinations = (from item in list
from item2 in list
where item < item2
select new Tuple<int, int>(item, item2)).ToList();
【讨论】:
1. 这将创建一个可枚举的列表。真的是你的意思吗?为什么不只是select Tuple.Create(item, item2)
? 2. 这将导致重复对,例如(1,4)
和 (4,1)
。不确定这是否是 OP 想要的,但看起来不像。
它还会创建(1,1)
,这在OPs示例中没有说明,也不是一对。但我想知道(1,4)
和(4,1)
是否重要。
@stakx @Mikael 所有重复的都可以被where item < item2
过滤掉。
感谢您的反馈。更新了我的答案以过滤掉重复项。
@Laroslav 仅当项目是为了开始,对吧?【参考方案3】:
你可以这样解决:
var list = new[] 1, 2, 3, 4 ;
var pairs = from l1 in list
from l2 in list.Except(new[] l1 )
where l1 < l2
select new l1, l2 ;
foreach (var pair in pairs)
Console.WriteLine(pair.l1 + ", " + pair.l2);
【讨论】:
以上是关于使用 LINQ 获取列表中的所有对的主要内容,如果未能解决你的问题,请参考以下文章