我有一组包含类型,日期和值的数据。
我想按类型分组,并且对于每组中的每组值,我想选择具有最新日期的那一组。
这是一些有效的代码并给出了正确的结果,但我想在一个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
答案 0 :(得分:7)
使用select
获取FirstOrDefault
(或First
- 因为您不会获得null的分组)有序降序:
var data = mydata.GroupBy(item => item.Type)
.Select(group => group.OrderByDescending(x => x.Date)
.FirstOrDefault())
.ToList();
或SelectMany
以及Take(1)
var data = mydata.GroupBy(item => item.Type)
.SelectMany(group => group.OrderByDescending(x => x.Date)
.Take(1))
.ToList();
答案 1 :(得分:2)
您可以Select
订购组的第一个元素:
var topItems = mydata.GroupBy(item => item.Type)
.Select(group => group.OrderByDescending(item => item.Date).First())
.ToList();
topItems
现在是List<Item>
,仅包含每Type
的热门商品。
您也可以Dictionary<string,Item>
将Type
字符串映射到Item
的顶部Type
来检索它:
var topItems = mydata.GroupBy(item => item.Type)
.ToDictionary(group => group.Key,
group => group.OrderByDescending(item => item.Date).First());
答案 2 :(得分:2)
var data = mydata.GroupBy(
item => item.Type,
(type, items) => items.OrderByDescending(item => item.Date).First());
foreach (var item in data)
{
Console.WriteLine($"{item.Type} {item.Date.ToString("yyyy-MM-dd")} {item.Value}");
}
答案 3 :(得分:1)
按类型分组,对于每个组,按日期降序排序并选择第一个(最新的)。
mydata.GroupBy(i => i.Type).Select(g => g.OrderByDescending(i => i.Date).First());