C#實如今foreach遍歷中刪除集合中的元素(方法總結)

[toc]html


在foreach中刪除元素時,每一次刪除都會致使集合的大小和元素索引值發生變化,從而致使在foreach中刪除元素時會拋出異常。dom

集合已修改;可能沒法執行枚舉操做。 在這裏插入圖片描述函數

方法一:採用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。spa

  • 用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;code

方法二:使用遞歸

使用遞歸,每次刪除之後都重新foreach,就不存在這個問題了;htm

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, 正確,可是每次都要封裝函數,通用性不強;blog

方法三:經過泛型類實現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);
            }
        }
    }

原文出處:https://www.cnblogs.com/willingtolove/p/12051649.html遞歸

相關文章
相關標籤/搜索