我有以下列表:
var items = new List<Tuple<string, int, int>>()
{
Tuple.Create("A", 3, 0),
Tuple.Create("A", 5, 0),
Tuple.Create("B", 1, 0),
Tuple.Create("C", 1, 0),
Tuple.Create("C", 3, 0),
Tuple.Create("C", 2, 0),
Tuple.Create("C", 3, 1)
};
我有以下提示:
var results = (from item in items
group item by item.Item1 into groupedItems
let maxPriority = groupedItems.Max(item => item.Item2)
from element in groupedItems
where element.Item2 == maxPriority
select element).Distinct();
我得到这个:
Name Priority
A 5
B 1
C 3
C 3
我只想区别如下:
Name Priority
A 5
B 1
C 3
有人知道如何修改linq来做到这一点吗?先谢谢你。
注意:我知道Distinct具有允许您传递IComparer的重载。但是,如果可以在linq语句本身上更简单地完成操作,我想避免这种情况。我也不希望使用Distinct语句。
答案 0 :(得分:1)
基本上,您要执行的操作是get the item from a sequence who has the max value for a particular selector function。因此,只需编写该函数(或使用其他人编写的函数)即可。请注意,在您的查询中,您要多次迭代序列以完成此操作,因此您可以做得更好。您只需执行一次即可实现该操作。
现在您要做的就是对分组的项目执行单个操作,您的查询将变得非常简单:
var query = items.GroupBy(item => item.Item1)
.Select(group => group.MaxBy(item => item.Item2));
答案 1 :(得分:0)
好吧,您的查询包含项的所有属性,因此当我执行此操作时,结果实际上是
Item1 Item2 Item3
A 5 0
B 1 0
C 3 0
C 3 1
因此,您的Distinct呼叫实际上行为正确。我假设,由于您仅查看前两个属性,因此还应仅将它们包括在结果中。然后,非重复呼叫实际上会为您提供所需的结果:
var results = (from item in items
group item by item.Item1 into groupedItems
let maxPriority = groupedItems.Max(item => item.Item2)
from element in groupedItems
where element.Item2 == maxPriority
select new {element.Item1, element.Item2}).Distinct();
请注意已替换的select new { ... }
。
更新:
然后,您的查询将类似于Matt的建议:
var results = (from item in items
group item by item.Item1 into groupedItems
let maxPriority = groupedItems.Max(item => item.Item2)
from element in groupedItems
where element.Item2 == maxPriority
group element by new { element.Item1, element.Item2 } into
groupByItem1Item2
select groupByItem1Item2.OrderByDescending(element => element.Item3).First());
只需在.OrderByDescending(element => element.Item3)
调用之前执行.First()
。
答案 2 :(得分:0)
在Item1,Item2上添加另一个分组,例如:
var results = (from item in items
group item by item.Item1 into groupedItems
let maxPriority = groupedItems.Max(item => item.Item2)
from element in groupedItems
where element.Item2 == maxPriority
group element by new { element.Item1, element.Item2 } into
groupByItem1Item2
select groupByItem1Item2.First());
答案 3 :(得分:0)
这里是使用lambas且不添加任何第三方库的纯LINQ解决方案:
var results = items.GroupBy(item => item.Item1)
.Select(grp => new {
Group = grp,
Item2Max = grp.Max(item => item.Item2)
})
.Select(x => new Tuple<string, int, int>(
x.Group.Key,
x.Item2Max,
x.Group.Where(item => item.Item2 == x.Item2Max).Max(item => item.Item3)
));
这将输出:
Item1 Item2 Item3
A 5 0
B 1 0
C 3 1