虽然尝试使用 LINQ 执行此操作是一个不错的练习,但效率不高。
GroupBy 将创建一个Dictionary<Tkey, ICollection<TResult>>,或者更准确地说:一个查找表。对于每个元素,它将提取键和 TResult。对于ever 元素,它会检查键是否在查找表中。
- 如果没有,它会将 TResult 放入新的
ICollection<TResult> 中,并将 Key 和集合添加到表中。
- 如果 Key 在表中,它会将 TResult 添加到集合的末尾。
这是一项相当多的工作,而实际上您唯一想要的就是:
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;
}
用法:
IEnumerable<double> inputData = ....
double sum = inputData.ToEveryOtherDouble().Sum();
如果您坚持使用 LINQ,请创建两个组:一组包含带有偶数索引的双精度数,另一组包含带有奇数索引的双精度数。
组的So Key: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
GroupBy 的结果:两组。键为 0 的组和键为 1 的组。键为 0 的组以偶数索引处的双精度为元素,键为 1 的组以奇数索引处的双精度为元素。
继续 LINQ:如果您只想要偶数索引:
.Where(group => group.Key == 0).Sum();
结论
选择权在你:哪一个更易于阅读、重用、维护和单元测试:
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();
或者:
double sum = inputData.ToEveryOtherDouble().Sum();