C#根据类属性过滤类列表字典

Posted

技术标签:

【中文标题】C#根据类属性过滤类列表字典【英文标题】:C# filter Dictionary of list of class based on class property 【发布时间】:2021-01-17 13:46:50 【问题描述】:

我有这本字典Dictionary<string, List<Payments>>,其中包含员工,每个员工都有一个付款清单。 Payments 类有一个名为 PayCategoryId 的字符串属性。我想过滤这本字典,只获取具有某些特定 PayCategoryId 值的付款的员工,并且对于每个员工只有这些付款。我很确定这可以通过使用 LINQ 来实现,但我对 LINQ 的经验几乎为零,所以需要你的帮助。

原始(未过滤)字典有 76 个项目(员工)。我将用作示例的员工有 27 笔付款,其中一些具有所需的 PayCategoryId。

我做了什么:

    具有所需 PayCategoryId 的列表:
    var payCategoriesID = new List<string> () "a", "b", "c" ;
    使用此 LINQ 对字典进行半过滤(我敢肯定它是一团糟,但它正在工作!):
    var result = dict.Where(o => o.Value.Where(x => payCategoriesID.Contains(x.PayCategoryId)).Any()).ToDictionary(mc => mc.Key, mc => mc.Value);
    半过滤结果字典只有 34 项。没有使用所需 PayCategoryId 付款的员工被过滤掉。但是我的示例员工仍然在列表中拥有所有 27 笔付款。我也需要过滤他的列表,并且只有 PayCategoryId = payCategoriesID 列表中的 ID 之一的付款。 当然,示例员工只是一个示例,所有员工都应该被过滤掉。

你能帮忙吗?

阿德里安

【问题讨论】:

【参考方案1】:

您可以使用Select() 投影到匿名类型的可枚举中并只获取您想要的值,然后重新构建一个字典。

var match = dict
        .Select(kv => new
        
            Employee = kv.Key,
            Payments = kv.Value.Where(p => payCategoriesID.Contains(p.PayCategoryId))
        )
        .Where(emp => emp.Payments.Any())
        .ToDictionary(k => k.Employee, v => v.Payments);

第一步创建一个带有键和过滤值的对象,然后Where() 删除空列表。这样,您只需遍历 ids 列表一次(字典中的每个元素)。


另外,不是真的相关,但 Any() 方法有一个重载,它接受一个谓词,所以不是

o.Value.Where(x => payCategoriesID.Contains(x.PayCategoryId)).Any()

你可以直接做

o.Value.Any(x => payCategoriesID.Contains(x.PayCategoryId))

Count()First()FirstOrDefault()Last() 等其他 LINQ 方法也是如此。

【讨论】:

优雅、简洁和解释。谢谢你,@colinD!【参考方案2】:
var result = dict.Where(o => o.Value.Where(x => payCategoriesID.Contains(x.PayCategoryId)).Any()).ToDictionary(mc => mc.Key, mc => mc.Value.Where(t=> payCategoriesID.Contains(t.PayCategoryId)));

【讨论】:

宾果游戏!和DOH! :) 非常感谢!

以上是关于C#根据类属性过滤类列表字典的主要内容,如果未能解决你的问题,请参考以下文章

C# - 将一个类的列表转换为具有相同属性的另一个类的列表[重复]

我们可以忽略类属性中的 c# 列表吗? [复制]

C#类属性的动态读取写入--SetValue--GetValue

《C#零基础入门之百识百例》(八十八)系统类Dictionary字典解析 -- 21点游戏

《C#零基础入门之百识百例》(八十八)系统类Dictionary字典解析 -- 21点游戏

抽象类的奏鸣曲管理员:如何按子类属性过滤