考虑以下记录:
Id F1 F2 F3
-------------------------------------------------
1 Nima 1990 10
2 Nima 1990 11
3 Nima 2000 12
4 John 2001 1
5 John 2002 2
6 Sara 2010 4
我想根据
F1
字段进行分组并按 Id
进行排序,并从类似于这些记录的组的第一条记录中获取所有字段:
Id F1 F2 F3
-------------------------------------------------
1 Nima 1990 10
4 John 2001 1
6 Sara 2010 4
如何使用 linq 执行此操作?
var result = input.GroupBy(x => x.F1, (key,g) => g.OrderBy(e => e.F2).First());
var res = from element in list
group element by element.F1
into groups
select groups.OrderBy(p => p.F2).First();
@Alireza 的 awnser 是完全正确的,但是使用此代码时您必须注意
var res = from element in list
group element by element.F1
into groups
select groups.OrderBy(p => p.F2).First();
这与此代码类似,因为您对列表进行排序,然后进行分组,这样您就获得了组的第一行
var res = (from element in list)
.OrderBy(x => x.F2)
.GroupBy(x => x.F1)
.Select()
现在,如果您想做一些更复杂的事情,例如采用相同的分组结果,但采用 F2 的第一个元素和 F3 的最后一个元素或更自定义的东西,您可以通过研究下面的代码来完成
var res = (from element in list)
.GroupBy(x => x.F1)
.Select(y => new
{
F1 = y.FirstOrDefault().F1;
F2 = y.First().F2;
F3 = y.Last().F3;
});
所以你会得到类似的东西
F1 F2 F3
-----------------------------------
Nima 1990 12
John 2001 2
Sara 2010 4
用它来实现你想要的。然后决定您要返回哪些属性。
yourList.OrderBy(l => l.Id).GroupBy(l => new { GroupName = l.F1}).Select(r => r.Key.GroupName)
另一种方式:
var result = input.GroupBy(i => i.F1).Select(g => g.First());
您可以按多个字段进行分组:
var result = input.GroupBy(i => new {i.F1, i.F2}).Select(g => g.First());
如果需要保持顺序,请使用查找:
var result = input.ToLookup(i => i.F1).Select(g => g.First());
var res = (from element in list)
.OrderBy(x => x.F2).AsEnumerable()
.GroupBy(x => x.F1)
.Select()
在 OrderBy() 之后使用 .AsEnumerable()
这并不完全是您正在寻找的东西,但有时我们会寻找错误的东西,因为我们不知道存在什么。所以我的解决方案是我发现最直观的:
var dict =
input.OrderByDescending(x => x.Id)
.GroupBy(x => x.F1)
.ToDictionary(x => x.Key, x => new { x.First().F1, x.First().F2, x.First().F3});
先订购,然后分组——直接进行。现在的结果将是一个键类型对列表❊。由于我们的表已经排序,我们可以选择第一个条目。另外,我建议将结果放入字典中,并以 ID 作为访问器,这是一种访问速度非常快的数据结构,而且仍然很灵活。现在您可以使用
访问它dict[4].F1 // returns John
❊ 从技术上讲,它是 IEnumerable