C#实现在foreach遍历中删除集合中的元素(方法总结)
在foreach中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,从而导致在foreach中删除元素时会抛出异常。
集合已修改;可能无法执行枚举操作。
方法一:采用for循环,并且从尾到头遍历
- 如果从头到尾正序遍历删除的话,有些符合删除条件的元素会成为漏网之鱼;
正序删除举例:
List<string> tempList = new List<string>() { "a","b","b","c" };
for (int i = 0; i < tempList.Count; i++)
{
if (tempList[i] == "b")
{
tempList.Remove(tempList[i]);
}
}
tempList.ForEach(p => {
Console.Write(p+",");
});
控制台输出结果:a,b,b,c
有两个2没有删除掉;
这是因为当i=1时,满足条件执行删除操作,会移除第一个b,接着第二个b会前移到第一个b的位置,即游标1对应的是第二个b。
接着遍历i=2,也就跳过第二个b。
- 用for倒序遍历删除,从尾到头
List<string> tempList = new List<string>() { "a","b","b","c" };
for (int i = tempList.Count-1; i>=0; i--)
{
if (tempList[i] == "b")
{
tempList.Remove(tempList[i]);
}
}
tempList.ForEach(p => {
Console.Write(p+",");
});
控制台输出结果:a,c,
这次删除了所有的b;
方法二:使用递归
使用递归,每次删除以后都从新foreach,就不存在这个问题了;
static void Main(string[] args)
{
List<string> tempList = new List<string>() { "a","b","b","c" };
RemoveTest(tempList);
tempList.ForEach(p => {
Console.Write(p+",");
});
}
static void RemoveTest(List<string> list)
{
foreach (var item in list)
{
if (item == "b")
{
list.Remove(item);
RemoveTest(list);
return;
}
}
}
控制台输出结果:a,c,
正确,但是每次都要封装函数,通用性不强;
方法三:通过泛型类实现IEnumerator
static void Main(string[] args)
{
RemoveClass<Group> tempList = new RemoveClass<Group>();
tempList.Add(new Group() { id = 1,name="Group1" }) ;
tempList.Add(new Group() { id = 2, name = "Group2" });
tempList.Add(new Group() { id = 2, name = "Group2" });
tempList.Add(new Group() { id = 3, name = "Group3" });
foreach (Group item in tempList)
{
if (item.id==2)
{
tempList.Remove(item);
}
}
foreach (Group item in tempList)
{
Console.Write(item.id+",");
}
//控制台输出结果:1,3
public class RemoveClass<T>
{
RemoveClassCollection<T> collection = new RemoveClassCollection<T>();
public IEnumerator GetEnumerator()
{
return collection;
}
public void Remove(T t)
{
collection.Remove(t);
}
public void Add(T t)
{
collection.Add(t);
}
}
public class RemoveClassCollection<T> : IEnumerator
{
List<T> list = new List<T>();
public object current = null;
Random rd = new Random();
public object Current
{
get { return current; }
}
int icout = 0;
public bool MoveNext()
{
if (icout >= list.Count)
{
return false;
}
else
{
current = list[icout];
icout++;
return true;
}
}
public void Reset()
{
icout = 0;
}
public void Add(T t)
{
list.Add(t);
}
public void Remove(T t)
{
if (list.Contains(t))
{
if (list.IndexOf(t) <= icout)
{
icout--;
}
list.Remove(t);
}
}
}
C#实现在foreach遍历中删除集合中的元素(方法总结)的更多相关文章
- C#实现在foreach中删除集合中的元素
List<string> str = new List<string>(); str.Add( "zs"); str.Add("ls") ...
- C#中删除集合中符合条件的元素以及需注意属相
如果用foreach,会造成被遍历的集合更改后带来异常问题. 此时,用for循环可有效的解决这个问题. for(int i=0;i<List.Count;i++) { if(条件是真) { Li ...
- 使用Properties集合存储数据,遍历取出Properties集合中的数据和Properties集合中的方法store和load
package com.yang.Test.PropertiesStudy; import java.io.FileWriter; import java.io.IOException; import ...
- Day_11【集合】扩展案例2_使用普通for循环获取集合中索引为3的元素并打印,统计集合中包含字符串"def"的数量,删除集合中的所有字符串",将集合中每个元素中的小写字母变成大写字母def",
分析以下需求,并用代码实现 1.定义ArrayList集合,存入多个字符串"abc" "def" "efg" "def" ...
- Java循环删除集合多个元素的正确打开方式
首先说下不正确的打开方式: 第一:使用for循环删除集合的元素,示例代码如下 ArrayList<String> list = new ArrayList<String>(Ar ...
- ArcGIS Engine中删除要素的几种方法总结
转自原文 ArcGIS Engine中删除要素的几种方法总结 /// <summary> /// 通过IFeature.Delete方法删除要素 /// </summary> ...
- 【转载】C#中List集合中Last和LastOrDefault方法的差别
在C#的List集合操作中,Last方法和LastOrDefault方法都会用来查找集合中最后一个符合条件的元素对象,但Last和LastOrDefault方法还是有差别的,建议使用LastOrDef ...
- 【转载】C#中List集合SingleOrDefault和FirstOrDefault方法有何不同
在C#的List集合类的操作过程中,有时候我们会使用到List集合的SingleOrDefault方法和FirstOrDefault等方法,这2个方法都是System.Linq.Enumerable类 ...
- 【转载】C#中List集合First和FirstOrDefault方法有何不同
在C#的List集合中查找一个符合条件的元素,一般我们会用First方法或者FirstOrDefault方法来返回第一个符合条件的对象,First方法和FirstOrDefault的调用都是使用Lam ...
随机推荐
- 【java】关于Cannot refer to the non-final local variable list defined in an enclosing scope解决方法
今天学习中遇到了一个问题: Cannot refer to the non-final local variable list defined in an enclosing scope 这里的new ...
- 什么是TCP, UDP, HTTP, HTTPS协议?
TCP 传输控制协议是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC793定义. TCP主要特点: 1. 面向连接: (1)应用程序在使用TCP协议之前,必须先建立TCP连接. ...
- 手把手带你一键部署 Kubernetes + KubeSphere 至 Linux
本文介绍一个最快安装 Kubernetes 和体验 KubeSphere 核心功能的方式,all-in-one 模式可一键安装 Kubernetes v1.15.5 和 KubeSphere 至一台 ...
- 详解在Linux系统中安装JDK
本文以在CentOS 7.6中安装JDK8为例进行安装,其他系统和版本都是大同小异的. 下载 进入Oracle官方网站的下载页面. 首先,接受许可协议,如下图: 然后,根据Linux系统的位数选择要下 ...
- Java基础IO类之字节输入输出流
一.IO流概述 1.IO流:输入输出流(Input/Output) 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象,即数据在设备间的传输流, 流的本质是数据传输,根据数据传输特性将 ...
- Dubbo实现登陆
一.目录展示 二.dubbo_logins_service 2.1 实体类和service层 2.2 logins实体类 package com.login.entity; import java.i ...
- scrapy抓取中国新闻网新闻
目标说明 利用scrapy抓取中新网新闻,关于自然灾害滑坡的全部国内新闻:要求主题为滑坡类新闻,包含灾害造成的经济损失等相关内容,并结合textrank算法,得到每篇新闻的关键词,便于后续文本挖掘分析 ...
- 使用aop加解密http接口
背景 最近在写一个小程序接口,由于安全性比较高,因此需要给请求参数和响应进行加密处理.如果在每个方法上都加密解密,那样代码就显得太繁琐了而且工作量会加大.所以,我们会统一进行加解密处理,一种比较传统的 ...
- 【开发工具 - Git】之本地项目托管到远程仓库
这里所说的“本地项目托管到远程仓库”,说的是:例如,我们在本地有一个写了很长时间的项目,现在想要托管到GitHub或码云上进行版本控制. 这个过程大致需要以下几个步骤: (1)在本地初始化Git项目本 ...
- CentOS 7 安装 bind 服务 实现内网DNS
目录 安装 配置 服务管理 测试 安装 废话不多说,直接安装 yum install -y bind bind-utils 配置 [root@jenkins named]# rpm -ql bind ...
