繁体   English   中英

C# 从列表中的总和中检索最接近 0 的绝对值

[英]C# Retrieving the absolute value closest to 0 from a sum in a list

我想要做的是获取每个IDTime Math.Abs(A + B + C)最接近 0 的时间。 它相当沉重。 我有一个看起来像这样的列表(我从 CSV 文件中获得):

        |------------|------------|-------|-------|-------|
        |    Time    |     ID     |   A   |   B   |   C   |
        |------------|------------|-------|-------|-------|
        |    100     |     1      |   1   |   2   |   2   |
        |------------|------------|-------|-------|-------| 
        |    100     |     2      |   3   |   4   |   3   |
        |------------|------------|-------|-------|-------| 
        |    200     |     1      |   1   |   0   |   3   |
        |------------|------------|-------|-------|-------| 
        |    200     |     2      |   1   |   2   |   0   |
        |------------|------------|-------|-------|-------| 

我有以下代码,虽然它还没有完成,但它在技术上打印了我想要的值。 但是,当我调试它时,它似乎并没有遍历 ID,而是在一个循环中完成了所有操作。 我的想法是我可以得到所有不同的ID ,然后 go 通过每个不同的Time ,将它们全部放在一个临时列表中,然后只需使用Aggregate获得最接近 0 的值。但我觉得应该有更多比这更有效的方法。 有没有更快的 LINQ function 我可以用来实现我想要的?

for (int i = 0; i < ExcelRecords.Select(x => x.Id).Distinct().Count(); i++)
        {
            for (int j = 0; j < ExcelRecords.Select(y => y.Time).Distinct().Count(); j++)
            {
                List<double> test = new List<double>();

                var a = ExcelRecords[j].a;
                var b = ExcelRecords[j].b;
                var c = ExcelRecords[j].c;
                test.Add(Math.Abs(pitch + yaw + roll));

                Console.WriteLine(Math.Abs(pitch + yaw + roll));
            }
        }

使用像这样的显式 for 循环将 LINQ 的功能和灵活性从 window 中剔除。 LINQ 的力量来自枚举器,它们可以单独使用,也可以与foreach循环结合使用。

您还需要使用Distinct首先获取一个列表,然后使用该列表选择性地将行分组为批次。 这就是GroupBy的设计目的。

var times = ExcelRecords.GroupBy((row) => row.Id)
                        .Select((g) => g.Aggregate((min, row) => Math.Abs(row.a + row.b + row.c) < Math.Abs(min.a + min.b + min.c) ? row : min).Time)
                        .ToList();

我认为最易读的方法是按Id分组,从每个组第Time订购每个组和 select:

var times = ExcelRecords.GroupBy(x => x.Id)
    .Select(grp => grp.OrderBy(item => Math.Abs(item.A + item.B + item.C)))
    .Select(grp => grp.First().Time);

工作示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM