当前位置: 首页 > news >正文

C# 两个list,查询属性相等的数据

目录

方法一:使用 HashSet + Where(推荐,性能最优)

方法二:使用 Join(适合需要获取双方数据)

方法三:使用 Intersect(仅适用于简单类型或重写 Equals 的自定义类)

总结建议


如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

在 C# 中查询两个 List 中某个属性值相等的数据(即求交集),最高效且常用的方法是使用HashSet配合 LINQ,或者直接使用 LINQ 的JoinIntersect方法。

以下是几种常见场景的实现方式:

方法一:使用 HashSet + Where(推荐,性能最优)

适用于数据量较大场景。先将其中一个列表的关键属性提取到HashSet中,利用其 O(1) 的查找效率进行过滤。

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() => $"Id: {Id}, Name: {Name}";
}

public static void Main()
{
var listA = new List<Item>
{
new Item { Id = 1, Name = "Apple" },
new Item { Id = 2, Name = "Banana" },
new Item { Id = 3, Name = "Cherry" }
};

var listB = new List<Item>
{
new Item { Id = 2, Name = "Banana" },
new Item { Id = 4, Name = "Date" },
new Item { Id = 5, Name = "Elderberry" }
};

// 1. 将 ListB 的 Id 放入 HashSet,提高查找效率
var bIds = new HashSet<int>(listB.Select(b => b.Id));

// 2. 查询 ListA 中 Id 存在于 HashSet 中的元素
var commonItems = listA.Where(a => bIds.Contains(a.Id)).ToList();

Console.WriteLine("属性(Id)相等的数据:");
foreach (var item in commonItems)
{
Console.WriteLine(item);
}
}
}

代码说明:

1. 使用 Select 提取 ListB 的 Id 并构建 HashSet,将查找复杂度降为 O(1)。

2. 使用 Where 遍历 ListA,通过 Contains 快速判断是否存在匹配项。

3. 此方法比嵌套循环或多次调用 Any/Contains 性能更高,适合大数据量。

方法二:使用 Join(适合需要获取双方数据)

如果你不仅需要 ListA 中的数据,还需要同时获取 ListB 中匹配的数据,或者进行更复杂的投影,使用Join是最直观的方式。

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() => $"Id: {Id}, Name: {Name}";
}

public static void Main()
{
var listA = new List<Item>
{
new Item { Id = 1, Name = "Apple" },
new Item { Id = 2, Name = "Banana" },
new Item { Id = 3, Name = "Cherry" }
};

var listB = new List<Item>
{
new Item { Id = 2, Name = "Banana" },
new Item { Id = 4, Name = "Date" }
};

// 使用 Join 基于 Id 关联两个列表
var result = from a in listA
join b in listB on a.Id equals b.Id
select new
{
ItemA = a,
ItemB = b
};

Console.WriteLine("Join 查询结果:");
foreach (var pair in result)
{
Console.WriteLine($"A: {pair.ItemA}, B: {pair.ItemB}");
}
}
}

代码说明:

1. 使用 LINQ 查询语法或方法语法的 Join 操作,基于指定属性(Id)进行内连接。

2. 可以灵活选择返回 ListA 的对象、ListB 的对象或两者的组合。

3. 底层实现通常也是基于哈希表,性能良好。

方法三:使用 Intersect(仅适用于简单类型或重写 Equals 的自定义类)

如果列表元素是基本类型(如int,string)或者自定义类重写了EqualsGetHashCode,可以直接使用Intersect

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
// 自定义类需重写 Equals 和 GetHashCode 才能正确使用 Intersect
public class Item : IEquatable<Item>
{
public int Id { get; set; }
public string Name { get; set; }

public bool Equals(Item other)
{
if (other is null) return false;
return Id == other.Id;
}

public override bool Equals(object obj) => Equals(obj as Item);

public override int GetHashCode() => Id.GetHashCode();

public override string ToString() => $"Id: {Id}, Name: {Name}";
}

public static void Main()
{
var listA = new List<Item>
{
new Item { Id = 1, Name = "Apple" },
new Item { Id = 2, Name = "Banana" }
};

var listB = new List<Item>
{
new Item { Id = 2, Name = "Banana" },
new Item { Id = 3, Name = "Cherry" }
};

// 直接求交集
var common = listA.Intersect(listB).ToList();

Console.WriteLine("Intersect 结果:");
foreach (var item in common)
{
Console.WriteLine(item);
}
}
}

代码说明:

1. Intersect 默认使用对象的 Equals 方法比较。

2. 对于自定义类,必须重写 Equals 和 GetHashCode,否则默认比较引用地址,导致无法正确找到逻辑上相等的对象。

3. 此方法简洁,但前提条件较多,不如前两种方法通用。

总结建议

  • 高性能通用方案‌:使用 ‌方法一(HashSet + Where)‌,代码清晰且性能稳定。
  • 需要双向数据‌:使用 ‌方法二(Join)‌。
  • 简单类型或已重写 Equals‌:使用 ‌方法三(Intersect)‌。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

http://www.jsqmd.com/news/1119621/

相关文章:

  • E-Hentai Downloader:高效漫画资源管理与智能下载全攻略
  • 如何用MusePose实现虚拟人舞蹈视频生成:从姿态对齐到高质量输出的完整指南
  • 3个步骤解锁BilibiliDown:让B站视频成为你的永久数字资产
  • 小龙虾技能-10-ai-llm-05_ModelSwitcher_模型切换
  • 卷积的学习
  • 冒险岛游戏资源提取器WzComparerR2:解密游戏素材的终极指南
  • 解锁音乐无限可能:Spotube插件化音乐流媒体体验指南
  • 一个装X的架构师,通过建文件夹就能亮瞎你的狗眼... ——传说中的弦哥
  • 数字IC设计流程及术语
  • C语言中的操作符详解(含三目表达式和逗号表达式)
  • 中断系统与外部中断EXTI
  • E-Hentai-Downloader:高效图库资源管理工具全解析
  • 3分钟掌握E-Hentai漫画批量下载:从零配置到高效管理的完整指南 [特殊字符]
  • 当Source引擎遇上Blender:如何让游戏资源在3D创作中重生?
  • 终极免费音乐解析工具:一个PHP接口搞定四大音乐平台
  • Linux管道与重定向实战技巧及Vim高效用法
  • C++ boost::log 详解:从基础到实战
  • 【电脑操作】C盘清理操作
  • 摆脱 SPSS 繁琐操作!okbiye 数据分析模块一站式搞定实证论文数据处理
  • 样本不多,模型也能练得很稳
  • mac新电脑-前端开发配置
  • E-Hentai Downloader:高效漫画批量下载工具的全方位应用指南
  • Claude Code 100个真实案例 - 用AI开发Electron桌面应用(Markdown笔记本)
  • Agent应用实践之四十 - OpenClaw:记忆
  • [LangChain中的Multi-Agent模式-03]Handoffs:状态驱动的多阶段流程编排与状态机管理
  • (论文速读)DEnet:零参考联合去噪与增强
  • 微信数据库解密原理与实战:基于AES-256-CBC与MD5密钥生成的数据恢复方案
  • 解决Kivy中文乱码问题:从方块乱码到完美显示
  • 一文打通AI舞蹈视频落地:用GPT-Image-2生图+Seedance2.0生成丝滑视频
  • 高效漫画资源管理:E-Hentai批量下载自动化方案