什么是正确的 Linq 语法,用于在单次迭代中从整数列表中获取多个聚合结果



我有一个整数列表,我想使用 Linq 语法计算:计数、最大值、最小值、平均值。 我知道以下内容都可以正常工作:

var avg = list.Average();
var max = list.Max(); 

等等。 但是我无法找出正确的 Linq 语法来在一次迭代中执行此操作,即相当于 SQL:

select Min(value), Max(value), Avg(value) from list

如果你的列表是src的,你可以使用ValueTupleAggregate来做一个难以阅读的循环:

var ans = src.Aggregate((Count: 0, Min: Int32.MaxValue, Max: Int32.MinValue, Sum: 0),
(g, v) => (g.Count+1, v < g.Min ? v : g.Min, v > g.Max ? v : g.Max, g.Sum+v));
var count = ans.Count;
var min = ans.Min;
var max = ans.Max;
var avg = ans.Sum / (double)(ans.Count == 0 ? 1 : ans.Count);

当然,如果这是您可能想要经常做的事情,您可以为其创建一个扩展方法:

public static class IEnumerableExt {
public static (int Count, int Min, int Max, double Average) Stats(this IEnumerable<int> src) {
var a = src.Aggregate((Count: 0, Min: Int32.MaxValue, Max: Int32.MinValue, Sum: 0),
(g, v) => (g.Count + 1, v < g.Min ? v : g.Min, v > g.Max ? v : g.Max, g.Sum + v));
return (a.Count, a.Min, a.Max, a.Sum / (double)(a.Count == 0 ? 1 : a.Count));
}
}

循环版本更冗长,但可以说更容易理解:

public static (int Count, int Min, int Max, double Average) Stats2(this IEnumerable<int> src) {
var count = 0;
var min = Int32.MaxValue;
var max = Int32.MinValue;
var sum = 0;
foreach (var i in src) {
++count;
if (i < min)
min = i;
if (i > max)
max = i;
sum += i;
}
return (count, min, max, sum / (double)(count == 0 ? 1 : count));
}

这个呢?在选择之前,订单列表ASC将很有用

List<double> list = new List<double>() { 15,116,17,21,333,44,55,11};
double max = 0;
double min = 0;
double avg = list.OrderBy(x => x).Select((x, index) => index == 0 ? min = x : max = x).Average();

希望有帮助,

最新更新