Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays LINQ中n个集合的置换生成_Arrays_Linq_Ienumerable_Permutation_Combinations - Fatal编程技术网

Arrays LINQ中n个集合的置换生成

Arrays LINQ中n个集合的置换生成,arrays,linq,ienumerable,permutation,combinations,Arrays,Linq,Ienumerable,Permutation,Combinations,我有一个IEnumerable(IEnumerable[])数组,并希望生成这些IEnumerable中所有可能的元素组合。 与此问题类似: 但是我不知道我之前会有多少IEnumerables,因此无法使用所描述的LINQ语句 举个例子: 我的阵列 例如,有这些元素 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}; arra

我有一个IEnumerable(IEnumerable[])数组,并希望生成这些IEnumerable中所有可能的元素组合。 与此问题类似: 但是我不知道我之前会有多少IEnumerables,因此无法使用所描述的LINQ语句

举个例子: 我的阵列

例如,有这些元素

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};
然后我需要适当的排列。我没有关于有多少IEnumerable的任何信息,也没有关于每个IEnumerable包含多少元素的信息

提前感谢您的帮助

Lars

尝试将此作为一个方向(我确信您需要修改,而且我还没有编译它,因此可能存在一些语法错误)

public IEnumerable编译名
(IEnumberable数组、列表组合)
{
如果(combinations==null)combinations=new List();
对于(int i=arrays.Count()-1;i>=0;i--)
{
如果(combinations.Count>=1)组合=
组合2列表(组合、数组[i]);
其他的
{
组合=组合2列表(数组[i],数组[i-1];
我--;
}
}
收益组合;
}
私有列表组合列表
(IEnumerable列表1、IEnumerable列表2)
{
List currentList=新列表();
对于(int i=0;i
同样,没有编译,但它应该做的是继续将“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]添加到第一个to之后将产生:
{a,1,x},{a,1,y},{a,1,z}
等等。

似乎您想要笛卡尔乘积。这应该可以,尽管我没有特别仔细地研究边缘情况

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);
        }
    }
    }
}
公共静态IEnumerable Drop(IEnumerable列表,长numToDrop)
{
if(numToDrop<0){throw new ArgumentException(“要删除的数字必须是非负的”);}
长期下降=0;
var iter=list.GetEnumerator();
而(drop
当您的输入是数组[0]={0,1,2};数组[1]={a,b};数组[2]={w,x,y,z}时,您希望输出是什么?如上所述,我不知道预期的输出真的算作所有的排列。你是否有一个假设的约束,即每个结果项只有两个元素?也可能是引用的重复:@David V:我的预期输出将是{0,a,w},{0,a,x},{0,a,y},{0,a,z},{0,b,x},{0,b,y},{0,b,z},{1,a,w}@Anthony Pegram:Eric Lippert的文章是我一直在寻找的,非常好而且干净。我只是还有一个问题。因为我说过我需要代码来处理一系列非类型的IEnumerable(IEnumerable[])我正在努力让Erics代码正常工作。使用类型化IEnumerables是完美的。尽管如上所述,Eric Lippert在Anthony linked问题上的解决方案要漂亮得多。谢谢Rob,这很有效!Eric的解决方案非常优雅,我同意,但因为我使用的是非类型化集合,所以我不能使用它(或不知道如何使用)。我的集合中的元素可以是从int到object的任何元素,尽管每个集合本身都是一致的。谢谢。我没有尝试过上面的代码,因为它对字符串进行操作,Rob的代码正是我所需要的,但仔细看,我想我可以很容易地修改它。
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;
}
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);
        }
    }
    }
}