我有一组包含类型,日期和值的数据。

我想按类型分组,对于每个组中的每个值集,我都希望选择一个具有最新日期的值。

这是一些可以正常工作并给出正确结果的代码,但我想在一个linq查询中而不是在迭代中全部完成。有什么想法我可以完全通过linq查询实现相同的结果吗?

using System;
using System.Linq;
using System.Collections.Generic;

public class Program {

    public static void Main() {

        var mydata = new List<Item> {
            new Item { Type = "A", Date = DateTime.Parse("2016/08/11"), Value = 1 },
            new Item { Type = "A", Date = DateTime.Parse("2016/08/12"), Value = 2 },
            new Item { Type = "B", Date = DateTime.Parse("2016/08/20"), Value = 3 },
            new Item { Type = "A", Date = DateTime.Parse("2016/08/09"), Value = 4 },
            new Item { Type = "A", Date = DateTime.Parse("2016/08/08"), Value = 5 },
            new Item { Type = "C", Date = DateTime.Parse("2016/08/17"), Value = 6 },
            new Item { Type = "B", Date = DateTime.Parse("2016/08/30"), Value = 7 },
            new Item { Type = "B", Date = DateTime.Parse("2016/08/18"), Value = 8 },
        };

        var data = mydata.GroupBy(_ => _.Type);

        foreach (var thing in data) {

            #region

            // How can I remove this section and make it part of the group by query above... ?
            var subset = thing.OrderByDescending(_ => _.Date);
            var top = subset.First();

            #endregion

            Console.WriteLine($"{thing.Key} {top.Date.ToString("yyyy-MM-dd")} {top.Value}");

        }
    }

    public class Item {

        public string Type {get;set;}
        public DateTime Date {get;set;}
        public int Value {get;set;}

    }
}

// Output:
//   A 2016-08-12 2
//   B 2016-08-30 7
//   C 2016-08-17 6

最佳答案

使用select获取FirstOrDefault(或First-由于分组的原因,您不会获得null)的降序排列:

var data = mydata.GroupBy(item => item.Type)
                 .Select(group => group.OrderByDescending(x => x.Date)
                 .FirstOrDefault())
                 .ToList();

SelectManyTake(1)
var data = mydata.GroupBy(item => item.Type)
                 .SelectMany(group => group.OrderByDescending(x => x.Date)
                 .Take(1))
                 .ToList();

09-25 11:06