使用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);
(如果需要,请使用ToList
或ToArray
。)
在非查询表达式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); }