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

标签 c# 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));
}

关于c# - 在单次迭代中从整数列表获取多个聚合结果的正确 Linq 语法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50590315/

相关文章:

多列上的 Linq orderby,其中一个可能为空

c# - ToLookup() 如何使用多个索引?

c# - 在 Linq 中选择子集

linq - 在 LINQ to Entities 中初始化强类型对象

c# - 对于结构,我是否必须在 C# 中显式调用构造函数?

c# - c#中使用AFORGE录制视频

c# - 诱发线程问题的好方法有哪些

c# 等价于 c++/cli long

c# - 数据标注中的错误信息如何本地化?

c# - 为什么要在 Method<type>() 中指定 <type> ?以及如何使用它?