嵌套循环遍历列表时移除元素引发的索引越界问题求解
解决列表遍历中移除元素导致的索引越界问题
嘿,我来帮你搞定这个问题!你推测的原因完全正确——当你在遍历myList1时移除元素,哪怕用了从后往前遍历的正确思路,内层循环的逻辑漏洞还是会导致索引越界。
先看看你当前代码的问题:
for (int i = myList1.Count - 1; i >= 0; i--) { for (int j = 0; j < myList2.Count - 1; j++) { if (myList2[j] != myList1[i]) { myList1.RemoveAt(i); } } }
这段代码的核心问题是:内层循环会多次检查myList1[i]和myList2的元素,只要有一个myList2[j]不等于它,就会执行移除操作。但如果myList1[i]已经被移除,内层循环后续迭代还会访问这个不存在的索引,直接触发索引越界异常。而且逻辑上这大概率不是你想要的——比如只要myList2里有一个元素不匹配,就移除myList1的元素,这会导致很多误删。
下面给你两种靠谱的修改方案:
方案1:修正逻辑,单次判断后移除
我们应该先判断myList1[i]是否**完全不存在于myList2**中,再执行移除,同时去掉冗余的内层循环,用Contains方法简化判断:
for (int i = myList1.Count - 1; i >= 0; i--) { // 只在元素完全不在myList2中时才移除 if (!myList2.Contains(myList1[i])) { myList1.RemoveAt(i); } }
从后往前遍历的思路保留了,同时每个元素只被检查和操作一次,彻底避免了重复移除或访问无效索引的问题。
方案2:用LINQ生成新列表(更简洁)
如果你能接受生成新列表而不是修改原列表,LINQ的写法会更简洁直观,完全规避索引问题:
myList1 = myList1.Where(item => myList2.Contains(item)).ToList();
这种写法直接筛选出myList1中存在于myList2的元素,生成新列表赋值给原变量,可读性拉满,也是C#开发中的惯用写法。
再补一句原代码的坑
原代码里内层循环的j < myList2.Count - 1也有问题——这会漏掉myList2的最后一个元素,应该改成j < myList2.Count才对,不过这个问题在上面的方案里已经被解决了。
内容的提问来源于stack exchange,提问作者Lewis
相关产品推荐
相关产品推荐

