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

时间:2019-07-15 12:11:22

标签: c# linq

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

假设您看到列表中有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进口日期= 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进口日期= 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。

我该如何实现? 我想我需要从列表中找到元素,然后找到给定名称和导入日期的狗的价格。然后使用结算方式更新列表中的元素

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

  

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

     

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

     

名称:Dog1价格:14.00年龄= 13进口日期= 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进口日期= 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

2 个答案:

答案 0 :(得分:5)

我建议从每个组创建 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中实现)不预先MaxBy(或MoreLinq);但可以使用Aggregate

进行仿真
     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)

答案 1 :(得分:3)

如果您不希望或无法创建新实例,则可以使用以下方法:

dogList = dogList
    .GroupBy(d => d.Name)
    .Select(dogGroup =>
    {
        Dog latestDog = dogGroup.OrderByDescending(d => d.ImportDate).First();
        if (!latestDog.Price.HasValue)
        {
            latestDog.Price = dogGroup
                .FirstOrDefault(dog => dog.Price.HasValue)?.Price.Value ?? null;
        }
        return latestDog;
    })
    .ToList();