#c# #linq #double #ienumerable
Вопрос:
Мне нужно вернуть сумму элементов с нечетными индексами в массиве двойников Это мой код:
public static double EvaluateSumOfElementsOddPositions(double[] inputData) { var sum = inputData .Select((v, i) =gt; new { Group = (i % 2 != 0), Value = v }) .GroupBy(x =gt; x.Group) .Select(g =gt; g.Sum(y =gt; y.Value)); return sum ; }
Но у меня есть ошибка: Не удается неявно преобразовать IEnumerable в double. Я не знаю, как я могу с этим справиться… Помогите, пожалуйста!
Комментарии:
1.
.Select(g =gt; g.Sum(y =gt; y.Value)).Sum()
2. Вы могли бы просто использовать переопределение where, подобное этому :
.Where((i,x)=gt; x % 2== 1).Sum();
Ответ №1:
То, что вы ищете, это что-то вроде:
public static double EvaluateSumOfElementsOddPositions(double[] inputData) { return inputData .Where((data, index) =gt; index % 2 != 0) .Sum(); }
Вам не нужно группировать элементы, если вы не собираетесь использовать элементы с четными индексами.
Комментарии:
1. @ТеСла Рад, что я смог помочь. Не могли бы вы, пожалуйста, озвучить ответ и отметить его как решение?
2. Я пробовал, но у меня получилось: Спасибо за отзыв! Вам нужно не менее 15 репутации, чтобы проголосовать, но ваши отзывы были записаны.
3. Хорошо, никаких проблем 🙂 Удачи с кодированием!
Ответ №2:
Хотя это хорошее упражнение, чтобы попытаться сделать это с помощью LINQ, оно не очень эффективно.
GroupBy создаст Dictionarylt;Tkey, ICollectionlt;TResultgt;gt;
, или, если быть более точным: Таблицу поиска. Для каждого элемента он извлечет ключ и результат. Для любого элемента он проверит, есть ли Ключ в таблице поиска.
- Если нет, он поместит результат в новый
ICollectionlt;TResultgt;
и добавит Ключ и коллекцию в таблицу. - Если ключ находится в таблице, он добавит результат в конец коллекции.
Это довольно большая работа, в то время как на самом деле единственное, что вам нужно, — это:
public static IEnumerablelt;doublegt; ToEveryOtherDouble(this IEnumerablelt;doublegt; doubles) { bool everyOther = false; // will return elements with index 1, 3, 5, ... // start with true if you want 0, 2, 4, ... foreach (double d in doubles) { if (everyOther) yield return d; everyOther = !everyOther; }
Использование:
IEnumerablelt;doublegt; inputData = .... double sum = inputData.ToEveryOtherDouble().Sum();
Если вы настаиваете на использовании LINQ, создайте две группы: группу, содержащую двойники с четными индексами, и группу, содержащую двойники с нечетными индексами.
Итак, ключ к группе: i % 2
double sum = inputData.Select( (d, index) =gt; new { Index = index, Value = d, }) .GroupBy(x =gt; x.Index % 2, // keySelector: groups with key 0 and key 1 // parameter elementSelector: specify the elements of each group x =gt; x.Value) // as elements of the group, we only need the double
Результат группового опроса: две группы. Группа с ключом 0 и группа с ключом 1. Группа с ключом 0 имеет в качестве элементов двойники по четным индексам, группа с ключом 1 имеет в качестве элементов двойники по нечетным индексам.
Продолжение LINQ: если вам нужны только четные индексы:
.Where(group =gt; group.Key == 0).Sum();
Вывод
Выбор за вами: какой из них проще для чтения, повторного использования, обслуживания и модульного тестирования:
double sum = inputData.Select( (d, index) =gt; new { Index = index, Value = d, }) .GroupBy(x =gt; x.Index % 2, x =gt; x.Value) .Where(group =gt; group.Key == 0) .Sum();
Или:
double sum = inputData.ToEveryOtherDouble().Sum();
Комментарии:
1. Почему бы просто не использовать
Where
переопределение без группировки?