I need return sum of elements with odd indexes in the array of doubles This is my code:
public static double EvaluateSumOfElementsOddPositions(double[] inputData)
{
var sum = inputData
.Select((v, i) => new { Group = (i % 2 != 0), Value = v })
.GroupBy(x => x.Group)
.Select(g => g.Sum(y => y.Value));
return sum ;
}
But I have a mistake: Can't implicitly convert IEnumerable to double. I don't know how I can deal with that... Help, please!
CodePudding user response:
What you are looking for is something like:
public static double EvaluateSumOfElementsOddPositions(double[] inputData)
{
return inputData
.Where((data, index) => index % 2 != 0)
.Sum();
}
You don't need to group the elements if you are not going to use elements at even indices.
CodePudding user response:
Although it is a nice exercise to try to do this using LINQ, it is not very efficient.
GroupBy will create a Dictionary<Tkey, ICollection<TResult>>
, or to be more precise: a Lookup Table. For every element, it will extract the key and the TResult. For ever element it will check if the Key is in the Lookup Table.
- If not, it will put the TResult in a new
ICollection<TResult>
and add the Key and the collection to the table. - It the Key is in the table it will add the TResult to the end of the collection.
This is quite a lot of work, while in fact the only thing you want is:
public static IEnumerable<double> ToEveryOtherDouble(this IEnumerable<double> 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;
}
Usage:
IEnumerable<double> inputData = ....
double sum = inputData.ToEveryOtherDouble().Sum();
If you insist on using LINQ, make two groups: a group containing doubles with the even indexes, and a group containing doubles with the odd indexes.
So Key of the group: i % 2
double sum = inputData.Select( (d, index) => new
{
Index = index,
Value = d,
})
.GroupBy(x => x.Index % 2, // keySelector: groups with key 0 and key 1
// parameter elementSelector: specify the elements of each group
x => x.Value) // as elements of the group, we only need the double
Result of the GroupBy: two groups. A group with key 0 and a group with key 1. The group with key 0 has as elements the doubles at even indexes, the group with key 1 has as elements the doubles at odd indexes.
Continuing the LINQ: if you want only the even indexes:
.Where(group => group.Key == 0).Sum();
Conclusion
The choice is yours: which one is easier to read, reuse, maintain and unit test:
double sum = inputData.Select( (d, index) => new
{
Index = index,
Value = d,
})
.GroupBy(x => x.Index % 2, x => x.Value)
.Where(group => group.Key == 0)
.Sum();
Or:
double sum = inputData.ToEveryOtherDouble().Sum();