【问题标题】:Filtering array of objects inside object based on predicate基于谓词过滤对象内部的对象数组
【发布时间】:2019-05-06 01:15:24
【问题描述】:

假设我有一个某种类型的对象,其中包含一个其他类型的数组:

public class Mammal
{
    public Leg[] Legs { get; set; }
}

public class Leg
{
    public int Length { get; }
}

如果我例如从一些GetMammals() 调用中收到Mammal,我将如何根据谓词(例如高度)过滤Legs 中的Mammal

Mammal.Legs.Where(l => l.Length > 10); 

上面会返回一个IEnumerable<Legs>,然后我必须找到一种方法将其填回Mammal,但是有没有一种巧妙的方法可以直接在我的Mammal对象上执行此操作,假设我必须这样做以后用这个filteredMammal 对象做其他事情?

【问题讨论】:

  • LINQ(语言集成query)是一个查询工具,它不会修改。如果你想修改,你必须自己做。
  • 由于您的数组是只读有效的,因此您无能为力。 Linq 只是返回集合而不是修改它们。
  • @HimBromBeere 好的,那么我们假设它不是只读的。
  • 您想修改Mammal.Legs 属性以使Leg 对象只有Length > 10 吗?如果你想在一行中完成,你可以编写一个Filter 扩展方法,它接受谓词并将属性设置为结果。
  • Eric Lippert on ForEach.

标签: c# linq filter


【解决方案1】:

您已经自己编写了解决方案。每个 linq 方法只是返回一个新集合,而不是修改现有的集合。

为此,您必须将返回的集合设置为您的哺乳动物属性:

myMammal.Legs = myMammals.Legs.Where(myPredicate).ToArray();

这假设您可以设置该属性。

另一个机会是写一个Remove-方法:

void Remove(Predicate<Leg> predicate)
{
    this.Legs = this.Legs.Where(x => !predicate(x)).ToArray();
}

这仍然需要 private 设置器。

最好的方法是将Legs 设置为List&lt;Leg&gt;。然后你就可以拨打RemoveAll:

myMammal.Legs.RemoveAll(myPredicate);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 2020-12-11
    • 1970-01-01
    相关资源
    最近更新 更多