我无法将这一点逻辑转换为Linq语句,这让我疯狂。我有一个包含类别和createdondate字段的项目列表。我希望按类别进行分组,只返回具有其类别的最大日期的项目。
因此,例如,列表包含具有类别1和2的项目。第一天(1/1)我将两个项目发布到类别1和2.第二天(1/2)我将三个项目发布到类别1.该列表应将第二天的帖子返回到第1类,将第一天的帖子返回到第2类。
现在我按类别进行分组,然后运行foreach循环,将组中的每个项目与组的最大日期进行比较,如果日期小于删除项目的最大日期。
必须有一种方法来解决这个问题,但我还没想到它!
答案 0 :(得分:2)
你可以这样做:
from item in list
group item by item.Category into g
select g.OrderByDescending(it => it.CreationDate).First();
但是,它效率不高,因为它需要对每个组的项进行排序,这比必要的更复杂(您实际上不需要排序,只需要扫描列表一次)。所以我创建了这个扩展方法来查找具有属性(或函数)的最大值的项:
public static T WithMax<T, TValue>(this IEnumerable<T> source, Func<T, TValue> selector)
{
var max = default(TValue);
var withMax = default(T);
var comparer = Comparer<TValue>.Default;
bool first = true;
foreach (var item in source)
{
var value = selector(item);
int compare = comparer.Compare(value, max);
if (compare > 0 || first)
{
max = value;
withMax = item;
}
first = false;
}
return withMax;
}
您可以按如下方式使用它:
from item in list
group item by item.Category into g
select g.WithMax(it => it.CreationDate);
更新:正如安东尼在评论中指出的那样,这段代码并没有完全回答这个问题...如果你想要所有项目的日期是他们类别的最大值,你可以这样做:
from item in list
group item by item.Category into g
let maxDate = g.Max(it => it.CreationDate)
select new
{
Category = g.Key,
Items = g.Where(it => it.CreationDate == maxDate)
};
答案 1 :(得分:1)
这个怎么样:
private class Test
{
public string Category { get; set; }
public DateTime PostDate { get; set; }
public string Post { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
List<Test> test = new List<Test>();
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 5, 12, 0, 0), Post = "A1" });
test.Add(new Test() { Category = "B", PostDate = new DateTime(2010, 5, 5, 13, 0, 0), Post = "B1" });
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 6, 12, 0, 0), Post = "A2" });
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 6, 13, 0, 0), Post = "A3" });
test.Add(new Test() { Category = "A", PostDate = new DateTime(2010, 5, 6, 14, 0, 0), Post = "A4" });
var q = test.GroupBy(t => t.Category).Select(g => new { grp = g, max = g.Max(t2 => t2.PostDate).Date }).SelectMany(x => x.grp.Where(t => t.PostDate >= x.max));
}
答案 2 :(得分:0)
重新格式化luc对查询理解形式的出色答案。我更喜欢这种查询,因为范围规则让我写得更简洁。
from item in source
group item by item.Category into g
let max = g.Max(item2 => item2.PostDate).Date
from item3 in g
where item3.PostDate.Date == max
select item3;