如何将 IEnumerable<IEnumerable<T>> 的多个列表添加到 IEnumerable<List<int>>

How to AddRange many lists of IEnumerable<IEnumerable<T>> into IEnumerable<List<int>>

我有那些功能

    public static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> items, int count)
    {
        int i = 0;
        foreach (var item in items)
        {
            if (count == 1)
                yield return new T[] { item };
            else
            {
                foreach (var result in GetPermutations(items.Skip(i + 1), count - 1))
                    yield return new T[] { item }.Concat(result);
            }

            ++i;
        }
    }

    public static List<List<int>> GetAllValidCombinations(List<int> items)
    {
        var finalList = new List<List<int>>();
        switch (items.Count)
        {
            case 1:
                finalList.Add(items);
                break;
            case 3:
                finalList.AddRange(GetPermutations(items, 2));
                finalList.AddRange((List<List<int>>)GetPermutations(items, 3));
                break;
        }
        return finalList;
    }

我想从 GetAllValidCombinations.

获取一个列表

在第 3 行 GetAllValidCombinations 的情况下,我得到: 错误 CS1503 参数 1:无法从 'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable>' 转换为 'System.Collections.Generic.IEnumerable<System.Collections.Generic.List>'

如果我尝试第二行,我会收到错误 Specified cast is not valid

如何在一行中完成此转换?

AddRange 期望 IEnumerableList,但您给它的 IEnumerableIEnumerable。那些 IEnumerable 可以是任何东西,不一定是列表,对吧?它们可能是集合或数组或我编写的其他类型,恰好实现了 IEnumerable<T>... 这就是编译器给您错误的原因。

而且正如你写的GetPermutations,我们可以看到它们实际上是T的数组!因此,您正在尝试将一堆数组添加到列表列表中!这没有多大意义,是吗?

幸运的是,ToList 将任何 IEnumerable 转换为 List。您应该使用 Select:

将此方法应用于嵌套在外部 IEnumerable 内的每个 IEnumerable
var enumerableOfEnumerables = GetPermutations(items, 2);
finalList.AddRange(enumerableOfEnumerables.Select(x => x.ToList()));

清道夫的答案很重要,您也可以通过仅使用内部集合中的列表并使其完全通用来稍微重构它。

public static IEnumerable<List<T>> GetPermutations<T>(List<T> items, int count)
{
   for (var index = 0; index < items.Count; index++)
      if (count == 1)
         yield return new List<T> { items[index] };
      else
         foreach (var result in GetPermutations(items.Skip(index + 1).ToList(), count - 1))
            yield return new List<T> { items[index] }
               .Concat(result)
               .ToList();
}

public static IEnumerable<List<T>> GetAllValidCombinations<T>(List<T> items)
{
   if (items.Count == 1)
       return new List<List<T>> {items};

   if (items.Count == 3)
      return GetPermutations(items, 2)
         .Concat(GetPermutations(items, 3));

   return Enumerable.Empty<List<T>>();
}

用法

var results = GetAllValidCombinations(new List<int>() {1, 2, 3});

foreach (var result in results)
   Console.WriteLine(string.Join(",",result));

输出

1,2
1,3
2,3
1,2,3

Full Demo Here