我有一个这种类型的列表List>包含这个
ListA = new List {1, 2, 3, 4, 5}; List B = new List {0, 1}; List C = new List {6}; List X = new List {....,....};
我希望拥有这样的所有组合
1-0-6 1-1-6 2-0-6 2-1-6 3-0-6
等等.
据你说这是使用Linq解决这个问题吗?
这与我给另一个问题的答案非常相似:
var combinations = from a in A from b in B from c in C orderby a, b, c select new List{ a, b, c }; var x = combinations.ToList();
对于可变数量的输入,现在添加了泛型:
var x = AllCombinationsOf(A, B, C); public static List> AllCombinationsOf
(params List [] sets) { // need array bounds checking etc for production var combinations = new List >(); // prime the data foreach (var value in sets[0]) combinations.Add(new List
{ value }); foreach (var set in sets.Skip(1)) combinations = AddExtraSet(combinations, set); return combinations; } private static List > AddExtraSet
(List > combinations, List
set) { var newCombinations = from value in set from combination in combinations select new List (combination) { value }; return newCombinations.ToList(); }
如果维度的数量是固定的,这只是SelectMany
:
var qry = from a in A from b in B from c in C select new {A=a,B=b,C=c};
但是,如果维度的数量由数据控制,则需要使用递归:
static void Main() { List> outerList = new List
> { new List
(){1, 2, 3, 4, 5}, new List (){0, 1}, new List (){6,3}, new List (){1,3,5} }; int[] result = new int[outerList.Count]; Recurse(result, 0, outerList); } static void Recurse (int[] selected, int index, IEnumerable remaining) where TList : IEnumerable { IEnumerable nextList = remaining.FirstOrDefault(); if (nextList == null) { StringBuilder sb = new StringBuilder(); foreach (int i in selected) { sb.Append(i).Append(','); } if (sb.Length > 0) sb.Length--; Console.WriteLine(sb); } else { foreach (int i in nextList) { selected[index] = i; Recurse(selected, index + 1, remaining.Skip(1)); } } }
如何使用.Join方法生成组合的方法如何?
static void Main() { List> collectionOfSeries = new List
> { new List
(){1, 2, 3, 4, 5}, new List (){0, 1}, new List (){6,3}, new List (){1,3,5} }; int[] result = new int[collectionOfSeries.Count]; List > combinations = GenerateCombinations(collectionOfSeries); Display(combinations); }
此方法GenerateCombinations(..)执行生成组合的主要工作.此方法是通用的,因此可用于生成任何类型的组合.
private static List> GenerateCombinations
( List > collectionOfSeries) { List
> generatedCombinations = collectionOfSeries.Take(1) .FirstOrDefault() .Select(i => (new T[]{i}).ToList()) .ToList(); foreach (List
series in collectionOfSeries.Skip(1)) { generatedCombinations = generatedCombinations .Join(series as List , combination => true, i => true, (combination, i) => { List nextLevelCombination = new List (combination); nextLevelCombination.Add(i); return nextLevelCombination; }).ToList(); } return generatedCombinations; }
显示助手..
private static void Display(List > generatedCombinations) { int index = 0; foreach (var generatedCombination in generatedCombinations) { Console.Write("{0}\t:", ++index); foreach (var i in generatedCombination) { Console.Write("{0,3}", i); } Console.WriteLine(); } Console.ReadKey(); }