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

Posted

技术标签:

【中文标题】如何将多个 IEnumerable<IEnumerable<T>> 列表添加到 IEnumerable<List<int>>【英文标题】:How to AddRange many lists of IEnumerable<IEnumerable<T>> into IEnumerable<List<int>> 【发布时间】:2020-12-07 04:17:06 【问题描述】:

我有这些功能

    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 获取一个 List。

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

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

我怎样才能在一行中做到这一点?

【问题讨论】:

finalList.AddRange(GetPermutations(items, 2).Select(x =&gt; x.ToList())); 【参考方案1】:

Sweepers 的回答很划算,您也可以通过仅使用内部集合中的列表并使其完全通用来对其进行一些重构。

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

【讨论】:

嗨@CDrosos,您是说它的行为不符合预期,还是有错误? 我希望 GetPermutations(items, 2) 提供一个 List 和 GetPermutations(items, 3) 提供另一个 List 并且它们都在 GetAllValidCombinations 将返回的另一个 List 上.通过您的实施,我认为返回的列表将只有一个列表 @CDrosos 啊是的,我明白你在说什么 @CDrosos 但是它确实如您所愿。它加入了 2 个集合集合并将它们返回到集合集合中。这与创建一个集合和 2 个 AddRanges 并返回结果相同 但您的实现将返回 GetAllValidCombinations(somethin).Count == 1 而我想要 GetAllValidCombinations(somethin).Count == 2。我希望 GetPermutations 结果在单独的列表中【参考方案2】:

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

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

幸运的是,ToList 将任何IEnumerable 转换为List。您应该将此方法应用于嵌套在外部IEnumerable 内的每个IEnumerable,使用Select

var enumerableOfEnumerables = GetPermutations(items, 2);
finalList.AddRange(enumerableOfEnumerables.Select(x => x.ToList()));

【讨论】:

你说得对,我知道如果没有一些演员表我所做的事情是没有意义的,但由于某种原因我无法找出一个单行演员表,谢谢

以上是关于如何将多个 IEnumerable<IEnumerable<T>> 列表添加到 IEnumerable<List<int>>的主要内容,如果未能解决你的问题,请参考以下文章

编写一个性能与数组foreach相当的IEnumerator

LINQ

如何将两个 IEnumerable<T> 连接成一个新的 IEnumerable<T>?

如何将项目添加到 IEnumerable<T> 集合?

在 C# 中将多个 IEnumerable<T> 提要混合为一个

如何将 JSON 字符串转换为 C# IEnumerable<JToken>