如何从List<A>中筛选Attributes键匹配Filters且按Name去重的元素?
解决方案:筛选并按Name去重List元素
这是个很常见的集合处理场景,用C#的LINQ就能轻松搞定,我直接给你完整实现和细节解释:
先修正下类A的语法(原代码有小问题)
首先得确保你的类A是可访问的,属性要有正确的访问修饰符:
public class A { public string Name { get; set; } public string AnotherProperty { get; set; } public Dictionary<string, string> Attributes { get; set; } }
核心筛选+去重逻辑
假设你已经初始化了listA和Filters,下面就是核心的LINQ代码:
using System.Linq; var filteredAndDistinctList = listA // 第一步:筛选出Attributes中至少有一个键存在于Filters的元素 .Where(a => a.Attributes?.Keys.Intersect(Filters).Any() == true) // 第二步:按Name分组,取每个分组的第一个元素实现去重 .GroupBy(a => a.Name) .Select(group => group.First()) .ToList();
代码细节解释
筛选条件:
Where(a => a.Attributes?.Keys.Intersect(Filters).Any() == true)- 用
?.空条件运算符处理Attributes可能为null的情况,避免空引用异常 Keys.Intersect(Filters)找出当前元素Attributes的键与Filters列表的交集Any()判断交集是否非空,也就是该元素的Attributes里至少有一个键符合筛选要求
- 用
按Name去重:
GroupBy(a => a.Name)把所有相同Name的元素归为一组Select(group => group.First())从每个分组中取出第一个元素,这样就保证了每个Name只保留第一个符合筛选条件的元素
可选变体
如果需要忽略Name的大小写进行去重,只需要修改GroupBy的比较器:
.GroupBy(a => a.Name, StringComparer.OrdinalIgnoreCase)
如果你的需求是Attributes的所有键都必须存在于Filters中(而不是至少一个),可以把筛选条件改成:
.Where(a => a.Attributes != null && a.Attributes.Keys.All(key => Filters.Contains(key)))
内容的提问来源于stack exchange,提问作者zav
相关产品推荐
相关产品推荐

