多个清单的组合 [英] Combinations of multiple list
问题描述
我不能完全确定组合"一词的正确性,但是我需要从一个或多个列表"中构建一个组合列表.每个列表将包含不同数量的元素,例如
I'm not completely sure that the term 'Combination' is correct, however I have a requirement to build a list of combination form one or more List. Each list will contain a varying number of elements, e.g.
List<string> lBag1 = ["1_0, 1_1, 1_3"]
List<string> lBag2 = ["11_0, 11_1, 11_8"]
List<string> lBag3 = ["3_0"]
我需要的是列表形式从1到n的所有组合,每个列表中的元素不超过一个,例如
What I need is all combination of the Lists form 1 to n elements with no more than one element from each list, e.g.
"1_0"
"1_1"
"1_3"
"11_0"
"11_1"
"11_8"
"3_0"
"1_0 11_0"
"1_0 11_1"
"1_0 11_8"
"1_0 3_0"
...
"1_3 11_8 3_0"
顺序并不重要,因此"1_0 11_0"被视为与"11_0 1_0"相同.
Order is not important, so "1_0 11_0" is considered the same as "11_0 1_0".
任何帮助将不胜感激
推荐答案
这两个扩展方法将使您可以将多个枚举链接在一起,从而计算出所需的组合.
These two extension methods will let you chain together several enumerations, calculating the combinations you want.
每个组合都是一个枚举,而不是连接的字符串.
Each combination is an enumeration, rather than a concatenated string.
// This method takes two sequences of T, and returns
// - each element of the first sequence,
// wrapped in its own one-element sequence
// - each element of the second sequence,
// wrapped in its own one-element sequence
// - each pair of elements (one from each sequence),
// as a two-element sequence.
// e.g. { 1 }.CrossWith({ 2 }) returns { { 1 }, { 2 }, { 1, 2 } }
public static IEnumerable<IEnumerable<T>> CrossWith<T>(
this IEnumerable<T> source1,
IEnumerable<T> source2)
{
foreach(T s1 in source1) yield return new[] { s1 };
foreach(T s2 in source2) yield return new[] { s2 };
foreach(T s1 in source1)
foreach(T s2 in source2)
yield return new[] { s1, s2 };
}
// This method takes a sequence of sequences of T and a sequence of T,
// and returns
// - each sequence from the first sequence
// - each element of the second sequence,
// wrapped in its own one-element sequence
// - each pair, with the element from the second sequence appended to the
// sequence from the first sequence.
// e.g. { { 1, 2 } }.CrossWith({ 3 }) returns
// { { 1, 2 }, { 3 }, { 1, 2, 3 } }
public static IEnumerable<IEnumerable<T>> CrossWith<T>(
this IEnumerable<IEnumerable<T>> source1,
IEnumerable<T> source2)
{
foreach(IEnumerable<T> s1 in source1) yield return s1;
foreach(T s2 in source2) yield return new[] { s2 };
foreach(IEnumerable<T> s1 in source1)
foreach(T s2 in source2)
yield return s1.Concat(new[] { s2 }).ToArray();
}
var cross = lBag1.CrossWith(lBag2).CrossWith(lBag3);
// { "1_0" }, { "1_1" }, { "1_3" } ...
// ... { "1_0", "11_0" }, ...
或者,还有经典的Eric Lippert 博客文章也做了类似的事情.(结果相似,方法截然不同.)
Alternatively, there is this classic Eric Lippert blog post that does a similar thing. (Similar result, very different method.)
这篇关于多个清单的组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!