You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C# LINQ筛选Dictionary中匹配指定ID的Person子集?

问题描述

现有以下C#代码定义的集合和类:

集合定义

Dictionary<int, Person[]> peopleSet = new() 
{
   { 1, new [] { new Person(11), new Person(22) } },
   { 2, new [] { new Person(33), new Person(44), new Person(55) } },
   { 3, new [] { new Person(66), new Person(77), new Person(88) } },
};

IEnumerable<int> ages = new [] { 11, 33, 44 };

Person类定义

public class Person
{
   public int Id { get; init; }

   public Person(int id)
   {
      Id = id;
   }
}

需要通过LINQ筛选得到如下结果:

Dictionary<int, Person[]> peopleSetLinq = new() 
{
   { 1, new [] { new Person(11) } },
   { 2, new [] { new Person(33), new Person(44) } }
};

要求:保留原Dictionary的键,仅保留值数组中Id存在于ages集合中的Person对象;若某个键对应的筛选后数组为空,则该键值对不保留。

解决方案

可以通过LINQ的Select和Where组合实现,同时为了提升查找效率,建议先把ages转换成HashSet<int>(HashSet的Contains操作时间复杂度为O(1),比IEnumerable的O(n)更高效)。

代码实现如下:

// 转换为HashSet提升查找性能
var ageSet = new HashSet<int>(ages);

var peopleSetLinq = peopleSet
    // 处理每个键值对,筛选符合条件的Person数组
    .Select(kv => new 
    {
        kv.Key,
        FilteredPeople = kv.Value.Where(p => ageSet.Contains(p.Id)).ToArray()
    })
    // 排除筛选后数组为空的键值对
    .Where(item => item.FilteredPeople.Length > 0)
    // 转换为目标Dictionary
    .ToDictionary(item => item.Key, item => item.FilteredPeople);

代码说明

  1. 转换为HashSet:将ages转为HashSet<int>,避免每次判断Id是否存在时都遍历整个集合,在ages元素较多时能显著提升性能。
  2. 处理每个键值对:对原Dictionary中的每个键值对,筛选出Id在ageSet中的Person对象并转为数组。
  3. 过滤空数组项:移除筛选后Person数组为空的键值对(比如原键3对应的所有Person都不在ages中,因此被排除)。
  4. 转换为目标结构:将处理后的结果转为Dictionary<int, Person[]>,得到符合需求的最终集合。

内容的提问来源于stack exchange,提问作者user22548444

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:15:02