首页 > 解决方案 > 如何使用重复值更新元素值?

问题描述

如何使用重复值更新元素值?

假设我的列表中有 4 个元素,如您所见,有 Dog1 和 Dog2 元素:

名称:Dog1 价格:NULL 年龄:14 ImportDate = 14.07.2019 15:00

名称:Dog1 价格:NULL 年龄:17 ImportDate = 14.07.2019 14:00

名称:Dog1 价格:14.00 年龄 = 13 ImportDate = 14.07.2019 13:00

名称:Dog2 价格:NULL 年龄:14 ImportDate = 14.07.2019 16:00

名称:Dog2 价格:NULL 年龄:17 ImportDate = 14.07.2019 10:00

名称:Dog2 价格:22.00 年龄 = 13 ImportDate = 14.07.2019 09:00

在列表中的这些元素中,我只想保留最新 ImportDate 的狗,我也想保留列表中的这两个元素:

名称:Dog1 价格:NULL 年龄:14 ImportDate = 14.07.2019 15:00

名称:Dog2 价格:NULL 年龄:14 ImportDate = 14.07.2019 16:00

在下面我提供了一个代码线来将这两只狗保留在列表中并删除其余的。

    dogList
      .GroupBy(x => new { 
         x.Name, 
         x.ImportDate.Date 
       })
      .Select(g => g
         .OrderByDescending(x => x.ImportDate)
         .First())
      .ToList();

但是我保留在列表中的两条狗没有任何价格。我想要做的是为这些价值为 NULL 的狗设置价格,以在特定日期对现有狗有价格,在这种情况下,最新的 dog1 应该有 14:00 的价格,而 dog2 应该有价格 22。

我怎样才能做到这一点?我想我需要从列表中找到元素,然后找到狗的名字和 importdate 的价格。然后使用结算更新列表中的元素

更新列表中的值后,结果应如下所示:

名称:Dog1 价格:14.00 年龄:14 ImportDate = 14.07.2019 15:00

名称:Dog1 价格:14.00 年龄:17 ImportDate = 14.07.2019 14:00

名称:Dog1 价格:14.00 年龄 = 13 ImportDate = 14.07.2019 13:00

名称:Dog2 价格:22.00 年龄:14 ImportDate = 14.07.2019 16:00

名称:Dog2 价格:22.00 年龄:17 ImportDate = 14.07.2019 10:00

名称:Dog2 价格:22.00 年龄 = 13 ImportDate = 14.07.2019 09:00

最终结果应该是一个包含这些元素的列表:

名称:Dog1 价格:14.00 年龄:14 ImportDate = 14.07.2019 15:00

名称:Dog2 价格:22.00 年龄:14 ImportDate = 14.07.2019 16:00

标签: c#linq

解决方案


我建议从每个组创建 Dog实例:

var filtered = dogList
  .GroupBy((item => new { 
     item.Name, 
     item.ImportDate.Date 
   })
  .Select(chunk => new Dog() { //TODO: Use the right syntax here
     Name       = chunk.Key.Name,
     ImportDate = chunk.Max(item => item.ImportDate), 
     Age        = chunk
       .Aggregate((s, a) => s.ImportDate < a.ImportDate ? s : a)
       .Age,  
     Price      = chunk.Where(item => item.Price.HasValue).Max(item => item.Price.Value)
   })
  .ToList();

编辑:主要原则(创建新Dog实例)保持不变,我们可能希望在最后更改一些评估Select

Name- 块的名称:

   Name = chunk.Key.Name

ImportDate- 最大可能:

   ImportDate = chunk.Max(item => item.ImportDate), 

Age- 年龄对应ImportDate。在这里,我们必须计算标准Linq中没有预置ArgMax的 (or MaxBy) (在 中实现);但可以模仿MoreLinqAggregate

     Age = chunk
       .Aggregate((s, a) => s.ImportDate < a.ImportDate ? s : a)
       .Age

最后,Price不为的最高价:

     Price = chunk.Where(item => item.Price.HasValue).Max(item => item.Price.Value)

推荐阅读