使用 Linq 基于属性构造不同的有序对象

本文关键字:对象 Linq 于属性 属性 使用 | 更新日期: 2023-09-27 18:23:56

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 }

使用 Linq 基于属性构造不同的有序对象

如果你的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中实施平等几乎肯定会更好:)

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

使用SelectMany()Concat()将子项组合成一个,并Distinct()使它们独一无二。