C# LINQ与集合类 数据操作
目录
LINQ语法
过滤数据
投影数据
排序数据
集合操作
聚合操作
分组操作
查找元素
其他操作
常用的集合类
List
LinkedList
HashSet
Dictionary
List:动态数组
LinkedList:双向链表
HashSet:唯一无序集合
Dictionary:键值对集合
场景代码示例
总结
集合类和LINQ是 C# 开发者处理数据的核心工具。本文通过一些常用的api简介数据操作。
LINQ语法
定义
LINQ语法是c#相对其它语言的优势。LINQ (Language Integrated Query) 被定义为一个用于数据查询的功能,它允许开发者通过统一的语法来查询不同类型的数据源,例如集合、数据库等。LINQ 提供了一个集成的查询语言,可以在编译时获得类型检,从而提高代码的可读性和安全性。LINQ 的关键特点包括:
集成查询:LINQ 将查询功能直接集成到 C# 中,而不需要独立的查询语言。这使得查询操作可以像其他编程操作一样嵌入到代码中。
一致的查询模型:无论查询的是集合、数据库、XML 或其他数据源,LINQ 提供了一个一致的查询模型和语法。
强类型和编译时验证:查询条件、投影等都能够在编译时进行类型检查,这减少了运行时错误的风险。
延迟执行:LINQ 查询通常是延迟执行的,只有在实际迭代查询结果时,查询才会被执行。这有助于优化性能,避免不必要的计算。
代码简洁:用简单的方法链实现复杂操作。
通过 LINQ,开发者可以在同一语言中对各种数据源进行复杂的查询操作,显著提高代码的简洁性、可维护性以及开发效率。
常用的方法
示例代码的参数可以简单理解为集合里的某一项,然后进行遍历
过滤数据
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Where | 过滤集合中满足条件的元素 | numbers.Where(n => n > 5); |
OfType<T> | 过滤出指定类型的元素 | objects.OfType<int>(); |
投影数据
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Select | 将集合中的元素映射到新的形式 | numbers.Select(n => n * 2); |
SelectMany | 将嵌套集合展开并映射 | students.SelectMany(s => s.Courses); |
排序数据
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
OrderBy | 按升序排序 | students.OrderBy(s => s.Age); |
OrderByDescending | 按降序排序 | students.OrderByDescending(s => s.Age); |
ThenBy | 在 OrderBy 后按另一条件排序 | students.OrderBy(s => s.Age).ThenBy(s => s.Name); |
ThenByDescending | 在 OrderBy 后按另一条件降序排序 | students.OrderBy(s => s.Age).ThenByDescending(s => s.Name); |
集合操作
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Distinct | 去重 | numbers.Distinct(); |
Union | 合并两个集合并去重 | numbers1.Union(numbers2); |
Intersect | 取两个集合的交集 | numbers1.Intersect(numbers2); |
Except | 取两个集合的差集 | numbers1.Except(numbers2); |
聚合操作
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Sum | 求和 | numbers.Sum(); |
Average | 求平均值 | numbers.Average(); |
Max | 求最大值 | numbers.Max(); |
Min | 求最小值 | numbers.Min(); |
Count | 统计元素个数 | numbers.Count(); |
分组操作
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
GroupBy | 按指定键分组 | students.GroupBy(s => s.Grade); |
查找元素
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
First | 返回第一个满足条件的元素 | numbers.First(n => n > 5); |
FirstOrDefault | 返回第一个满足条件的元素,若无则返回默认值 | numbers.FirstOrDefault(n => n > 5); |
Single | 返回唯一满足条件的元素 | numbers.Single(n => n == 5); |
SingleOrDefault | 返回唯一满足条件的元素,若无则返回默认值 | numbers.SingleOrDefault(n => n == 5); |
Last | 返回最后一个满足条件的元素 | numbers.Last(n => n > 5); |
LastOrDefault | 返回最后一个满足条件的元素,若无则返回默认值 | numbers.LastOrDefault(n => n > 5); |
其他操作
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Any | 判断集合中是否有满足条件的元素 | numbers.Any(n => n > 10); |
All | 判断集合中所有元素是否满足条件 | numbers.All(n => n > 0); |
Skip | 跳过指定数量的元素 | numbers.Skip(5); |
Take | 获取指定数量的元素 | numbers.Take(5); |
Concat | 连接两个集合 | numbers1.Concat(numbers2); |
Reverse | 反转集合 | numbers.Reverse(); |
常用的集合类
操作方法
List<T>
List<T> 是动态数组,提供了丰富的操作方法。
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Add | 添加一个元素到列表末尾 | list.Add(10); |
AddRange | 添加一个集合到列表末尾 | list.AddRange(new[] { 20, 30 }); |
Insert | 在指定索引处插入一个元素 | list.Insert(1, 40); |
Remove | 移除第一个匹配的元素 | list.Remove(10); |
RemoveAt | 移除指定索引处的元素 | list.RemoveAt(2); |
RemoveRange | 移除指定范围的元素 | list.RemoveRange(0, 2); |
Clear | 清空列表 | list.Clear(); |
Contains | 判断列表是否包含某个元素 | list.Contains(10); |
IndexOf | 查找元素的索引 | list.IndexOf(10); |
Find | 查找第一个匹配的元素 | list.Find(x => x > 5); |
FindAll | 查找所有匹配的元素 | list.FindAll(x => x > 5); |
Sort | 对列表进行排序 | list.Sort(); |
Reverse | 反转列表 | list.Reverse(); |
Count | 获取列表的元素数量 | list.Count; |
ToArray | 将列表转换为数组 | list.ToArray(); |
LinkedList<T>
LinkedList<T> 是双向链表,适合频繁插入和删除操作。
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
AddFirst | 在链表头部插入一个元素 | linkedList.AddFirst(10); |
AddLast | 在链表尾部插入一个元素 | linkedList.AddLast(20); |
AddBefore | 在指定节点前插入一个元素 | linkedList.AddBefore(linkedList.First, 30); |
AddAfter | 在指定节点后插入一个元素 | linkedList.AddAfter(linkedList.First, 40); |
RemoveFirst | 移除链表头部的元素 | linkedList.RemoveFirst(); |
RemoveLast | 移除链表尾部的元素 | linkedList.RemoveLast(); |
Remove | 移除第一个匹配的元素 | linkedList.Remove(10); |
Clear | 清空链表 | linkedList.Clear(); |
Contains | 判断链表是否包含某个元素 | linkedList.Contains(10); |
Count | 获取链表的元素数量 | linkedList.Count; |
First | 获取链表的第一个节点 | linkedList.First; |
Last | 获取链表的最后一个节点 | linkedList.Last; |
HashSet<T>
HashSet<T> 是无序且唯一的集合,适合需要快速查找、插入和删除的场景。
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Add | 添加一个元素,若已存在则返回 false | hashSet.Add(10); |
Remove | 移除指定元素 | hashSet.Remove(10); |
Clear | 清空集合 | hashSet.Clear(); |
Contains | 判断集合是否包含指定元素 | hashSet.Contains(10); |
UnionWith | 并集操作 | hashSet.UnionWith(otherSet); |
IntersectWith | 交集操作 | hashSet.IntersectWith(otherSet); |
ExceptWith | 差集操作 | hashSet.ExceptWith(otherSet); |
SymmetricExceptWith | 对称差集操作(只保留不重叠的元素) | hashSet.SymmetricExceptWith(otherSet); |
Count | 获取集合的元素数量 | hashSet.Count; |
Dictionary<TKey, TValue>
Dictionary<TKey, TValue> 是键值对集合,支持通过键快速查找值。
| 方法名 | 功能描述 | 示例代码 |
|---|---|---|
Add | 添加一个键值对 | dict.Add("key1", "value1"); |
Remove | 移除指定键的键值对 | dict.Remove("key1"); |
Clear | 清空字典 | dict.Clear(); |
ContainsKey | 判断字典是否包含指定键 | dict.ContainsKey("key1"); |
ContainsValue | 判断字典是否包含指定值 | dict.ContainsValue("value1"); |
TryGetValue | 尝试获取指定键的值,返回是否成功 | dict.TryGetValue("key1", out string value); |
Keys | 获取所有键的集合 | dict.Keys; |
Values | 获取所有值的集合 | dict.Values; |
Count | 获取字典的元素数量 | dict.Count; |
方法示例
List<T>:动态数组
使用场景:元素频繁增删改查,但不要求唯一性。
// 创建并添加元素
List<string> list = new List<string> { "Apple", "Banana" };
list.Add("Cherry"); // 添加到末尾// 删除元素
list.Remove("Banana"); // 删除第一次出现的元素
list.RemoveAt(0); // 删除索引位置元素// 遍历(LINQ格式)
list.ForEach(fruit => Console.WriteLine(fruit));
LinkedList<T>:双向链表
使用场景:频繁在两端的插入/删除操作。
LinkedList<int> linkedList = new LinkedList<int>();
linkedList.AddLast(10); // 尾部添加
linkedList.AddFirst(20); // 头部添加LinkedListNode<int> node = linkedList.Find(10);
linkedList.AddAfter(node, 15); // 在节点后插入新值linkedList.RemoveFirst(); // 删除头节点
HashSet<T>:唯一无序集合
使用场景:去重、集合运算(并集/交集)。
HashSet<int> setA = new HashSet<int> { 1, 2, 3 };
HashSet<int> setB = new HashSet<int> { 3, 4, 5 };setA.UnionWith(setB); // 并集:1, 2, 3, 4, 5
setA.IntersectWith(setB); // 交集:3
setA.ExceptWith(setB); // 差集:1, 2bool contains = setA.Contains(3); // 检查是否包含
Dictionary<TKey, TValue>:键值对集合
使用场景:高效查找(通过键)、存储复杂数据。
Dictionary<string, int> ages = new Dictionary<string, int>
{{ "Alice", 25 },{ "Bob", 30 }
};ages["Charlie"] = 35; // 添加新键值对
ages.Remove("Bob"); // 删除键值对if (ages.ContainsKey("Alice")) // 检查键是否存在
{int age = ages["Alice"]; // 通过键获取值
}
场景代码示例
从列表中筛选并排序
var students = new List<Student>
{new Student { Name = "Alice", Age = 20 },new Student { Name = "Bob", Age = 22 },new Student { Name = "Charlie", Age = 19 }
};var result = students.Where(s => s.Age >= 20) // 筛选年龄 >= 20 的学生.OrderBy(s => s.Age) // 按年龄升序排序.Select(s => s.Name); // 投影名字
统计字符串中每个单词的出现次数
string text = "Hello world! Hello C#!";
var wordCounts = text.Split(' ').GroupBy(word => word).Select(group => new { Word = group.Key, Count = group.Count() });
foreach (var word in wordCounts)
{Console.WriteLine($"{word.Word}: {word.Count}");
}
使用 Dictionary 和 LINQ 实现缓存
Dictionary<int, string> cache = new Dictionary<int, string>();
cache[1] = "Value1";
cache[2] = "Value2";var cachedKeys = cache.Keys.Where(key => key % 2 == 0); // 查找偶数键
总结
集合类和 LINQ 不仅简化了数据的存储和查询,还极大地提升了代码的可读性和开发效率。掌握集合类和 LINQ 能够编写更高效、更易维护的代码。如何高效地管理和处理数据,是每个开发者都需要面对的关键问题。
相关文章:
C# LINQ与集合类 数据操作
目录 LINQ语法 过滤数据 投影数据 排序数据 集合操作 聚合操作 分组操作 查找元素 其他操作 常用的集合类 List LinkedList HashSet Dictionary List:动态数组 LinkedList:双向链表 HashSet:唯一无序集合 Dictionary&…...
开源流程引擎对比:compileflow、Turbo、Warm-Flow、 flowable、activiti
文章目录 开源流程引擎对比I 工作流引擎阿里的Compileflowflowableactivitiwarm-flow(国产)Turbo (didiopensource)II 知识扩展开发流程开源流程引擎对比 ActivitiCamundaCompileflowturbo核心表量282205特性 中断可重入√√√支持回滚√√运行模式独立运行和内嵌独立运行和…...
golang使用sqlite3,开启wal模式,并发读写
因为sqlite是基于文件的,所以默认情况下,sqlite是不支持并发读写的,即写操作会阻塞其他操作,同时sqlite也很容易就产生死锁。 但是作为一个使用广泛的离线数据库,从sqlite3.7.0版本开始(SQLite Release 3.…...
基于yolov11的阿尔兹海默症严重程度检测系统python源码+onnx模型+评估指标曲线+精美GUI界面
【算法介绍】 基于YOLOv11的阿尔兹海默症严重程度检测系统是一种创新的医疗辅助工具,旨在通过先进的计算机视觉技术提高阿尔兹海默症的早期诊断和病情监测效率。阿尔兹海默症是一种渐进性的神经退行性疾病,通常表现为认知障碍、记忆丧失和语言障碍等症状…...
UV - Python 包管理
文章目录 创建 uv 项目已有项目已有uv项目 创建 uv 项目 # 创建项目 uv init m3 # 创建环境 cd m3 uv venv --python 3.11 # 激活环境 source .venv/bin/activate # 添加库 uv add flask 如果创建项目后,给库取别的名字,add 的时候,会…...
设计模式-生产者消费者模型
阻塞队列: 在介绍生产消费者模型之前,我们先认识一下阻塞队列。 阻塞队列是一种支持阻塞操作的队列,常用于生产者消费者模型,它提供了线程安全的队列操作,并且在队列为空或满时,能够阻塞等待,…...
RabbitMQ介绍以及基本使用
文章目录 一、什么是消息队列? 二、消息队列的作用(优点) 1、解耦 2、流量削峰 3、异步 4、顺序性 三、RabbitMQ基本结构 四、RabbitMQ队列模式 1、简单队列模式 2、工作队列模式 3、发布/订阅模式 4、路由模式 5、主题模式 6、…...
shell解决xml文本中筛选的问题
shell解决xml文本中筛选的问题,将xml文件中多余的配置删除掉,达到符合单一配置的结果。 过于简单就不废话了。 #!/bin/bashconf_file$1 flag0 temp_file"__temp.xml"if [ -f "${temp_file}" ];thenrm "${temp_file}" fi …...
嵌入式硬件篇---OpenMV的硬件流和软件流
文章目录 前言一、硬件流控制(Hardware Flow Control)1. 基本原理RTSCTS 2. OpenMV中的实现• 硬件要求• 代码配置• 工作流程 二、软件流控制(Software Flow Control)1. 基本原理XONXOFF 2. OpenMV中的实现• 代码配置• 工作流…...
1.6 学习测试用例(Test)分为几步?
文章目录 前言一、什么是UVM中的测试用例(Test)?二、如何理解UVM中的测试用例?三、如何使用UVM中的测试用例?四、实操代码示例4.1代码结构4.2 代码实现4.2.1 a. 测试用例类的定义和实现4.2.2 b. 测试环境的构建和配置4…...
PDF2.0 投影注释(Projection annotations)
投影注释是PDF2.0新标准中新增加的注释类型,属于标记注释的子类型,因此,它具有很多其他标记注释的功能。 然而,投影注释仅在特定的运行时环境的上下文中有效,例如已激活的3D模型。 投影注释的注释字典包含了所有注释字…...
【AIGC提示词系统】基于 DeepSeek R1 + ClaudeAI 易经占卜系统
上篇因为是VIP,这篇来一个免费的 提示词在最下方,喜欢的点个关注吧 引言 在人工智能与传统文化交融的今天,如何让AI系统能够传递传统易经文化的智慧,同时保持易经本身的神秘感和权威性,是一个极具挑战性的课题。本文将…...
OpenAI 实战进阶教程 - 第十节 : 结合第三方工具的向量数据库Pinecone
面向读者群体 本节课程主要面向有一定编程基础和数据处理经验的计算机从业人员,如后端开发工程师、数据工程师以及对 AI 应用有浓厚兴趣的技术人员。即使你之前没使用过向量数据库,也可以通过本节的实操内容快速上手,为企业或个人项目构建强…...
深入Linux系列之进程地址空间
深入Linux系列之进程地址空间 1.引入 那么在之前的学习中,我们知道我们创建一个子进程的话,我们可以在代码层面调用fork函数来创建我们的子进程,那么fork函数的返回值根据我们当前所处进程的上下文是返回不同的值,它在父进程中返…...
AWK系统学习指南:从文本处理到数据分析的终极武器 介绍
目录 一、AWK核心设计哲学解析 1.1 记录与字段的原子模型 1.2 模式-动作范式 二、AWK编程语言深度解析 2.1 控制结构 说明: 2.2 关联数组 代码说明: 示例输入和输出: 注意事项: 2.3 内置函数库 三、高级应用技巧 3.1…...
250207-MacOS修改Ollama模型下载及运行的路径
在 macOS 上,Ollama 默认将模型存储在 ~/.ollama/models 目录。如果您希望更改模型的存储路径,可以通过设置环境变量 OLLAMA_MODELS 来实现。具体步骤如下: 选择新的模型存储目录:首先,确定您希望存储模型的目标目录路…...
1、http介绍
一、HTTP 和 HTTPS 简介 HTTP(HyperText Transfer Protocol) 用途:用于网页数据传输(不加密)。协议特性:以明文形式传输数据,默认端口 80,无身份验证和完整性保护。典型场景…...
半导体行业跨网文件交换系统
在当今这个数字化转型的时代,半导体行业作为技术密集型产业,正面临着前所未有的信息安全挑战。随着企业内外网隔离措施的加强,如何实现既安全又高效的跨网文件交换,成为了众多半导体企业的一大难题。 特别是在研发和生产过程中产生…...
使用GD32F470的硬件SPI读写W25Q64
代码简单改下引脚定义便可以使用! 使用的单片机具体型号:GD32F470ZGT6 简单介绍下W25Q64: /* W25Q64 性能参数 */ /* 容量:8MByte 64Mbit */ /* 有128个块,每个块有64KByte */ /* 每个块有16个扇区,每个…...
02为什么 OD门和 OC门输出必须加上拉电阻?
为什么 OD(开漏)门和 OC(开集)门输出必须加上拉电阻? 1、首先一点,知道OD是说的MOS管,OC是说的三极管,二者的区别与联系大家应该都懂。 2、以OC门举例,芯片的OC门内部结…...
保姆级教程--DeepSeek部署
以DeepSeek-R1或其他类似模型为例,涵盖环境配置、代码部署和运行测试的全流程: 准备工作 1. 注册 Cloud Studio - 访问 [Cloud Studio 官网](https://cloudstudio.net/),使用腾讯云账号登录。 - 完成实名认证(如需长期使用…...
AI方案调研与实践 (不定期补充)
目录 说明 1. AI云主机准备 1.1 Ollama配置 设置模型保存路径 配置模型驻留内存时间 查看GPU状况命令: nvidia-smi 2. Deepseek 2.1 安装与使用 3. LobeChat配置 参考 说明 调研并实例化各种AI方案,探索训练/使用方式的最佳实践。 1. AI云主机准备 可以去一…...
人工智能大模型之模型蒸馏与知识蒸馏
一、背景介绍 随着人工智能技术的不断发展,大模型在各个领域的应用也越来越广泛。模型蒸馏(Model Distillation)和知识蒸馏(Knowledge Distillation)是两种非常重要的模型压缩技术,它们可以帮助我们将大型…...
[手机Linux] onepluse6T 系统重新分区
一,刷入TWRP 1. 电脑下载 Fastboot 工具(解压备用)和对应机型 TWRP(.img 后缀文件,将其放入前面解压的文件夹里) 或者直接这里下载:TWRP 2. 将手机关机,长按音量上和下键 开机键 进入 fastbo…...
k8s部署elasticsearch
前置环境:已部署k8s集群,ip地址为 192.168.10.1~192.168.10.5,总共5台机器。 1. 创建provisioner制备器(如果已存在,则不需要) 制备器的具体部署方式,参考我之前的文章:k8s部署rab…...
知识图谱智能应用系统:数据分析与挖掘技术文档
一、概述 在知识图谱智能应用系统中,数据分析与挖掘模块是实现知识发现和智能应用的核心环节。该模块负责处理和分析来自数据采集与预处理模块的结构化和半结构化数据,提取有价值的知识,并将其转化为可用于知识图谱构建和应用的三元组数据。本技术文档详细介绍了数据分析与…...
YAML中的`---`:文档分隔符
前言 YAML(YAML Ain’t Markup Language)是一种简洁且易于人类阅读的数据序列化标准,广泛用于配置文件、数据存储以及应用程序之间的数据交换。然而,对于许多初学者来说,YAML的一些特性可能不太直观,比如-…...
本地部署DeepSeek
下载Docker Docker Desktop: The #1 Containerization Tool for Developers | Docker 下载安装ollama Download Ollama on macOS 下载完成后解压运行 终端输入 Ollama --version 输出对应版本号即为下载成功 如果没有弹出上述图片,浏览器输入http://localhos…...
21.[前端开发]Day21-HTML5新增内容-CSS函数-BFC-媒体查询
王者荣耀-网页缩小的问题处理 为什么会产生这个问题?怎么去解决 可以给body设置最小宽度 1 HTML5新增元素 HTML5语义化元素 HTML5其他新增元素 2 Video、Audio元素 HTML5新增元素 - video video支持的视频格式 video的兼容性写法 HTML5新增元素 - audio audio…...
nbmade-boot调用deepseek的api过程与显示
希望大家一起能参与我的新开源项目nbmade-boot: 宁波智能制造低代码实训平台 下面简单介绍调用最近大红的AI :deepseek的api过程与显示,包括前后端代码与效果图 一、后端代码 1、几个基础的java类 DeepSeekRequest .java package com.nbcio.demo.do…...
