使用LINQ获取列表中的所有对

如何获取列表中所有可能的项目对(顺序不相关)?

例如,如果我有

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) } 

轻微重新设计cgeers的答案是为了获得你想要的元组而不是数组:

 var combinations = from item1 in list from item2 in list where item1 < item2 select Tuple.Create(item1, item2); 

(如果需要,请使用ToListToArray 。)

在非查询表达式forms(稍微重新排序):

 var combinations = list.SelectMany(x => list, (x, y) => Tuple.Create(x, y)) .Where(tuple => tuple.Item1 < tuple.Item2); 

这两个实际上都会考虑n 2个值而不是n 2/2个值,尽管它们最终会得到正确的答案。 另一种选择是:

 var combinations = list.Select((value, index) => new { value, index }) .SelectMany(x => list.Skip(x.index + 1), (x, y) => Tuple.Create(x.value, y)); 

...但是这使用了Skip ,也可能没有优化。 说实话,这可能没关系 - 我会选择最适合您使用的一个。

计算笛卡尔积以确定所有可能的组合。

例如:

 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>(); foreach (var pair in combinations) { var tuple = new Tuple(pair[0], pair[1]); pairs.Add(tuple); } 

或者简而言之:

 var combinations = (from item in list from item2 in list where item < item2 select new Tuple(item, item2)).ToList(); 

你可以像这样解决它:

  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); }