c# - 使用 LINQ 返回不同值的平均值

标签 c# linq

我对 LINQ 没有太多经验,并且在使用 LINQ 根据不同列中的不同值提取 ListView 列的平均值、众数和中位数时遇到困难。

例如,考虑以下数据:

ReportID  TAT  Col3  Col4  etc...
--------  ---  ----  ----  -------
80424     9    1     7     ...
80424     9    2     3     ...
80424     9    2     2     ...
80423     5    1     5     ...
80425     4    1     5     ...
80423     7    1     4     ...
82541     7    1     5     ...

要提取 TAT(周转时间)超过 5 天的不同报告的计数,我使用以下命令:

int countDistinctReports = (from ListViewItem itm in lvList.Items
                            where itm.SubItems[1].Text) > 5
                            select itm.SubItems[0].Text
                           ).Distinct().Count();

countDistinctReports 的值为 3。

为了提取这些报告的最小 TAT,我使用以下方法:

string minVal = (from ListViewItem itm in lvList.Items
             where itm.SubItems[1].Text) > 5
             select itm.SubItems[1].Text
            ).Min();

minVal 的值为 7。

但是,我不知道如何编写 LINQ 表达式来计算 TAT 大于 5 的不同报告的平均值、众数和中位数 TAT。在上面的示例中,平均值应为 (9+7+7 )/3 = 7.67。众数应为 7。

有人可以帮忙吗?非常感谢。

最佳答案

这是仅使用 linq 1-liners 重现和解决的问题:

using System;
using System.Linq;

namespace StackOverflow_StatisticsLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            var reports = new int[][]
            {
                new int[] {80424, 9, 1, 7},
                new int[] {80424, 9, 2, 3},
                new int[] {80424, 9, 2, 2},
                new int[] {80423, 5, 1, 5},
                new int[] {80425, 4, 1, 5},
                new int[] {80423, 7, 1, 4},
                new int[] {80541, 7, 1, 5}
            };

            var reportsTat5Plus = (
                    from int[] r in reports
                    where r[1] > 5
                    orderby r[1] descending
                    select r)
                .GroupBy(r => r[0])
                .Select(r => r.First()); // ensure ids are distinct
            
            var average = reportsTat5Plus.Select(r => r[1]).Average();
            
            var mode = reportsTat5Plus.GroupBy(v => v)
                .OrderByDescending(g => g.Count())
                .First()
                .Select(r => r[1])
                .First();
            
            var median = reportsTat5Plus.Count() % 2 == 1
                ? reportsTat5Plus.Skip(reportsTat5Plus.Count() / 2 + 1).Select(r => r[1]).First()
                : reportsTat5Plus.Skip(reportsTat5Plus.Count() / 2 - 1).Take(2).Select(r => r[1]).Average();

            Console.WriteLine($"Average: {average}");
            Console.WriteLine($"mode: {mode}");
            Console.WriteLine($"median: {median}");
            Console.ReadKey();
        }
    }
}

关于c# - 使用 LINQ 返回不同值的平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43134692/

相关文章:

C# 相当于 VB LINQ 查询

sql-server - 如何使用 List 参数编译 LINQ 查询?

c# - 从 ???_GetDisplayData 和 GROUP 数据中按天选择 DataTable(只有一些值),其中组规则对于不同的列是不同的

c# - 选择 Table.Value == 最大值

c# - 在 Biztalk Orchestration 中创建新消息的最佳方式是什么?

c# - 在 C# 中显式转换为枚举

c# - 在调用 ToList() 或 Count() 之前检查 LINQ Where() 是否返回任何内容

.net - 我的 linq 查询的返回类型是什么?

c# - 如何使用 Dynamic Linq 进行左外连接?

c# - 如何创建自定义 FluentAssertion 错误消息?