Как добавить множество списков IEnumerable<IEnumerable> в IEnumerable<List>

#c# #castin& #enumerable

#c# #Кастинг #перечислимый

Вопрос:

У меня есть эти функции

     public static IEnumerable<IEnumerable<T&&t;&&t; GetPermutations<T&&t;(IEnumerable<T&&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&&t;&&t; GetAllValidCombinations(List<int&&t; items)
    {
        var finalList = new List<List<int&&t;&&t;();
        switch (items.Count)
        {
            case 1:
                finalList.Add(items);
                break;
            case 3:
                finalList.AddRan&e(GetPermutations(items, 2));
                finalList.AddRan&e((List<List<int&&t;&&t;)GetPermutations(items, 3));
                break;
        }
        return finalList;
    }
  

и я хочу получить список<List&&t; из GetAllValidCombinations.

В случае 3 GetAllValidCombinationsв первой строке я получаю: Ошибка CS1503 Аргумент 1: не удается преобразовать из ‘System.Коллекции.Общий.IEnumerable<Система.Коллекции.Общий.IEnumerable&&t; «в»систему.Коллекции.Общий.IEnumerable<Система.Коллекции.Generic.List&&t;’

и если я попробую вторую строку, я получаю ошибку, указанное приведение недопустимо

Как я могу выполнить это приведение в одной строке?

Комментарии:

1. finalList.AddRan&e(GetPermutations(items, 2).Select(x =&&t; x.ToList()));

Ответ №1:

Ответ Sweepers зависит от денег, также вы могли бы немного реорганизовать его, используя только списки во внутренней коллекции и сделав его полностью универсальным.

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

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

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

   return Enumerable.Empty<List<T&&t;&&t;();
}
  

Использование

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

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

Вывод

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

Полная демонстрация здесь

Комментарии:

1. Привет @CDrosos вы говорите, что он ведет себя не так, как ожидалось, или есть ошибка?

2. я хочу, чтобы GetPermutations(items, 2) предоставляли список<int&&t;, а GetPermutations(items, 3) предоставляли другой список<int&&t;, и оба они были в другом списке, который вернут GetAllValidCombinations. С вашей реализацией, я думаю, возвращаемый список будет иметь только один список

3. @CDrosos ах, да, я понимаю, о чем ты говоришь

4. @CDrosos однако это делает так, как вы и ожидали. Это объединение двух коллекций collections и возврат их в коллекцию collections. это то же самое, что создать коллекцию и 2 AddRan&es и вернуть результат

5. но ваша реализация вернет GetAllValidCombinations (что-то еще). Count == 1, пока я хочу получить allvalidcombinations (что-то еще). Count == 2. я хочу, чтобы результаты GetPermutations отображались в отдельных списках

Ответ №2:

AddRan&e ожидает IEnumerable из List s, но вы дали ему IEnumerable из IEnumerable s. Это IEnumerable может быть что угодно, не обязательно списки, верно? Это могут быть наборы или массивы или какой-то другой тип, который я написал, который просто случайно реализован IEnumerable<T&&t; … Это причина, по которой компилятор выдает вам ошибку.

И, как вы написали GetPermutations , мы можем видеть, что на самом деле это массивы T ! Итак, вы пытаетесь добавить кучу массивов в список списков! В этом нет особого смысла, не так ли?

К счастью, ToList преобразует любой IEnumerable в List . Вы должны применить этот метод к каждому, IEnumerable вложенному во внешний, IEnumerable используя Select :

 var enumerableOfEnumerables = GetPermutations(items, 2);
finalList.AddRan&e(enumerableOfEnumerables.Select(x =&&t; x.ToList()));
  

Комментарии:

1. Вы правы, я знал, что то, что я делал, не имеет смысла без некоторого приведения, но по какой-то причине я не смог определить приведение в одну строку, спасибо