我有一个IEnumerable(IEnumerable [])数组,并希望在这些IEnumerables中生成所有可能的元素组合。 它类似于这个问题:Generating Permutations using LINQ 但是我不知道我预先会有多少IEnumerables,因此不能使用描述的LINQ语句。
举个例子: 我的阵列
IEnumerable[] array;
有例如这些元素
array[0]={0,1,2};
array[1]={a,b};
然后我想要退回这些:
{{0,a},{0,b},{1,a},{1,b},{2,a},{2,b}}
但也可能有:
array[0]={0,1,2};
array[1]={a,b};
array[2]={w,x,y,z};
然后我需要适当的排列。我没有关于有多少IEnumerables的信息,也没有关于每个IEnumerable包含多少元素的信息。
提前感谢您的帮助,
拉斯
答案 0 :(得分:0)
尝试这个方向(你需要修改,我确定,我还没有编译它,所以可能会有一些语法错误)
public IEnumerable<string> CompileCominations
(IEnumberable<string[]> arrays, List<string> combinations)
{
if(combinations == null) combinations = new List<string>();
for(int i = arrays.Count() - 1; i >= 0; i--)
{
if(combinations.Count >= 1) combinations =
Combine2Lists(combinations, arrays[i]);
else
{
combinations = Combine2Lists(arrays[i], arrays[i -1];
i--;
}
}
return combinations;
}
private List<string> Combine2Lists
(IEnumberable<string> list1, IEnumerable<string> list2)
{
List<string> currentList = new List<string>();
for(int i = 0; i < list1.Count(); i ++)
{
for(int j = 0; j < list2.Count(); j++)
{
currentList.Add(
string.Format("{0},{1}", list1[i], list2[j]);
}
}
return currentList;
}
同样,未编译,但 应该做的是继续将“item1,item2”添加到列表中,其中item1 =旧的“item1,item2”和item2 =只是新条目来自第n个数组。
因此字符串数组[a,b,c] +字符串数组[1,2,3,4]应该产生:{a, 1}, {a, 2}, {a, 3}, {a, 4}, {b, 1}...
并将字符串数组[x,y,z]添加到第一个然后收益率:{a, 1, x}, {a, 1, y}, {a, 1, z}
等等。
答案 1 :(得分:0)
好像你想要Cartesian_product。这应该有用,虽然我没有特别仔细地看边缘情况
public static IEnumerable<T> Drop<T>(IEnumerable<T> list, long numToDrop)
{
if (numToDrop < 0) { throw new ArgumentException("Number to drop must be non-negative"); }
long dropped = 0;
var iter = list.GetEnumerator();
while (dropped < numToDrop && iter.MoveNext()) { dropped++; }
while (iter.MoveNext()) { yield return iter.Current; }
}
public static IEnumerable Concat(object head, IEnumerable list)
{
yield return head;
foreach (var x in list) { yield return x; }
}
public static IEnumerable<IEnumerable> CrossProduct(IEnumerable<IEnumerable> lists)
{
if (lists == null || lists.FirstOrDefault() == null) { yield break; }
var heads = lists.First();
var tails = CrossProduct(Drop(lists, 1));
if (tails.FirstOrDefault() == null)
{
foreach (var h in heads) { yield return new object[] { h }; }
}
else
{
foreach (var head in heads)
{
foreach (var tail in tails)
{
yield return Concat(head, tail);
}
}
}
}