考虑以下类层次结构:
public class Foo
{
public string Name { get; set; }
public int Value { get; set; }
}
public class Bar
{
public string Name { get; set; }
public IEnumerable<Foo> TheFoo { get; set; }
}
public class Host
{
public void Go()
{
IEnumerable<Bar> allBar = //Build up some large list
//Get Dictionary<Bar, Foo> with max foo value
}
}
我想用Linq2Objects做的是得到一个KeyValuePair,对于allBBar集合中的每个Bar,我们选择具有最大Value属性的Foo。这可以在单个LINQ语句中轻松完成吗?
答案 0 :(得分:2)
当然,虽然我首选的解决方案使用MaxBy
中的MoreLINQ:
var query = allBar.ToDictionary(x => x, // Key
x => x.TheFoo.MaxBy(f => f.Value));
请注意,如果TheFoo
个实例的Bar
为空,则会形成梨状。
答案 1 :(得分:1)
另一种使用Aggregate而不是OrderBy的方法,以便计算出最大Foo是O(n)而不是O(n log n):
var query = allBar.ToDictionary(
bar => bar,
bar => bar.TheFoo.Aggregate(
null,
(max, foo) => (max == null || foo.Value > max.Value) ? foo : max));
答案 2 :(得分:0)
只是为了添加Jon关于MaxBy的评论,如果你没有foos,你可以做一个OrderByDescending然后使用FirstOrDefault获取Max元素。如果集合为空,它只返回null而不是“梨形”。
var foobars = bars.ToDictionary(bar => bar,
bar => bar.TheFoo.OrderByDescending(foo => foo.Value).FirstOrDefault());
我认为这不会像MaxBy那样高效,但在空集合的情况下它会更强大。