【问题标题】:How to extract some data from a collection using lambda/linq to objects?如何使用 lambda/linq 从集合中提取一些数据到对象?
【发布时间】:2009-01-14 01:24:22
【问题描述】:

我有一个IList<Animals> farmAnimals;

这个列表有三种类型,

  • 奶牛

如何使用 lambda 查询linq-to-objects 从列表中删除所有鸡,所以我现在有一个单独的鸡列表和原始列表只有牛和羊。

我是否必须创建三个列表(原始列表 + 2 个新列表,已过滤),然后将原始列表清空?还是有更棘手的方法?

结果需要

IList<Aniamls> chickens;
IList<Animals> farmAnimals; // only contains the cows and sheep, now.

干杯!

澄清问题:

什么性能更好? FindAll 和 RemoveAll 与 Where 建议的对比?

【问题讨论】:

    标签: c# .net lambda linq-to-objects


    【解决方案1】:

    假设:

    public abstract class Animal {}
    
    public class Chicken : Animal {}
    

    你可以这样做:

    var chickens = animals.OfType<Chicken>().Cast<Animal>().ToList();
    
    var nonChickens = animals.Except(chickens).ToList();
    

    编辑

    任何合理的答案都应该是O(n),这意味着原始列表中的每个项目只处理一次。因此,我建议采用命令式方法:

    var chickens = new List<Animal>();
    var nonChickens = new List<Animal>();
    
    foreach(var animal in animals)
    {
        var list = animal is Chicken ? chickens : nonChickens;
    
        list.Add(animal);
    }
    

    【讨论】:

    • Except 与 RemoveAll 和 OfType+Cast 与 FindAll 之间是否存在性能差异?
    【解决方案2】:
    var chickens = farmAnimals.Where(a => a.GetType() == typeof(Chicken)).ToList();
    farmAnimals = farmAnimals.Where(a => a.GetType() != typeof(Chicken)).ToList();
    

    【讨论】:

    • 对 Where 的有趣使用。也许用“is”检查替换 typeof 检查。
    【解决方案3】:
    var chickens = farmAnimals.ToList().FindAll (c => c.Type == "Chicken");
    farmAnimals.RemoveAll(a => a.Type=="Chicken");
    

    【讨论】:

    • RemoveAll 不返回 int 吗?那是 LEFT 还是 REMOVED 的项目数?我也更喜欢 'is' 而不是 .Type == 'blah'。
    • 其实RemoveAll并没有返回一个集合,它返回的是删除的项目数。
    • hmm,c 是你的 Animal 类 c.Type 是 Animal.Type 这是你问的什么?
    • 不。 c => c is Chicken 是正确的,因为 Chicken : Animal(鸡继承动物)。
    • 对不起 RemoveAll,我的错
    【解决方案4】:

    var Chickens = farmAnimals.FindAll(a=>a is Chicken);

    我非常倾向于选择最简单的解决方案。在这种情况下,使用 lambda 只需要 .NET Framework 2.0。 LINQ 扩展方法需要 3.5。

    【讨论】:

    • 我认为 Lambda 需要 C# 3.0,而不是 2.0。
    • 正确,语言规范 3.0 - 但它将在 Framework 2.0 上编译和运行,不需要 Framework 3 或 3.5。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多