使用Linq根据属性构造不同的,有序的对象

时间:2012-02-09 06:54:13

标签: c# linq

class Foo()
{
    public Bar [] bars;
}

class Bar ()
{
    public string name;
    public int id;
}

我有IEnumerable<Foo>并且我想构建一个IEnumerable<Bar>,其中包含每个唯一的栏(并按ID排序......但我可以自己处理该部分)。

我觉得这是LINQ制作的任务类型。但我似乎无法弄清楚如何实现它。

举个例子,如果我有:

foo[0] => bars { { name = "one", id = 1 }, { name = "two", id = 2 }, { name = "three", id = 3 },
foo[1] => bars { { name = "four", id = 4 }, { name = "four", id = 4 }

我希望我的linq语句返回:

{ name = "one", id = 1 }, { name = "two", id = 2 }, { name = "three", id = 3 }, { name = "four", id = 4 }

3 个答案:

答案 0 :(得分:4)

如果您的Bar课程覆盖EqualsGetHashCode,则会非常简单:

var values = foo.SelectMany(f => f.bars)
                .Distinct()
                .OrderBy(b => b.id);

如果没有这种平等实现,您需要创建自己的IEqualityComparer<Foo>以传递到Distinct方法。

如果您只需关心id使其与众不同,您可以使用MoreLINQ中的DistinctBy来简化您的生活:

var values = foo.SelectMany(f => f.bars)
                .DistinctBy(b => b.id)
                .OrderBy(b => b.id);

或者你可以使用匿名类型作为快速黑客来获得两个值之间的相等比较器,仍然使用MoreLINQ:

var values = foo.SelectMany(f => f.bars)
                .DistinctBy(b => new { b.id, b.name })
                .OrderBy(b => b.id);

Bar中实现平等几乎肯定会更好:尽管:)

答案 1 :(得分:0)

Foos.SelectMany(foo => foo.bars).OrderBy(bar => bar.id).Distinct()

答案 2 :(得分:0)

使用SelectMany()Concat()将儿童合并为一个Distinct()以使其独一无二。