#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. Вы правы, я знал, что то, что я делал, не имеет смысла без некоторого приведения, но по какой-то причине я не смог определить приведение в одну строку, спасибо