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#类属性的动态读取写入--SetValue--GetValue
《C#零基础入门之百识百例》(八十八)系统类Dictionary字典解析 -- 21点游戏