LINQ - 从嵌套集合中选择正确的值

时间:2009-07-08 21:14:50

标签: linq linq-to-objects

考虑以下类层次结构:

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语句中轻松完成吗?

3 个答案:

答案 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那样高效,但在空集合的情况下它会更强大。