2009-10-07 218 views
23

,以便消除XElements,我有一個bug,除去在foreach循環

foreach (XElement x in items.Elements("x")) 
{ 
    XElement result = webservice.method(x); 

    if (/*condition based on values in result*/) 
    { 
     x.Remove(); 
    } 
} 

的問題是,調用x.Remove()改變的foreach這樣,如果有兩個元素(「X」),並且第一個被刪除,循環不會到達第二個x元素。

那麼我該如何循環呢?還是應該以另一種方式重寫?

+8

其實我剛纔修改的foreach是「的foreach(在items.Elements的XElement X(」 X「)。反向())」,並且似乎正常工作的問題之前是在foreach移動索引向上,並且「刪除」將所有內容都向下移動,導致項目被跳過。顛倒秩序似乎是有道理的。但是,如果有人有更好的解決方案,我會將問題解決。 – CaffGeek 2009-10-07 17:00:48

+0

我做了一個循環,我不得不做一個我 - 如果它實際上刪除了一個項目來彌補索引。儘管如此,你的方式似乎並不是一個壞的選擇,但我不是一個.NET專家,所以我有點懷疑我說的是什麼,哈哈。 – Xaisoft 2009-10-07 17:09:28

+0

轉換爲C#3.0。有沒有C#版本3.5(詳細信息請參閱此文章http://stackoverflow.com/questions/247621/what-are-the-correct-version-numbers-for-c) – Vaccano 2009-10-16 19:46:25

回答

30

我懷疑Linq可能能夠幫助你在這裏如下。

using System.Linq; 

void foo() 
{ 
    items.Elements("x") 
     .Where(x => condition(webservice.method(x))) 
     .Remove(); 
} 

如果不工作(即,內部枚舉仍然無效),使所選擇的元素的淺拷貝和刪除它們如下。

using System.Linq; 

void foo() 
{ 
    List xElements = items.Elements("x") 
          .Where(x => condition(webservice.method(x))) 
          .ToList(); 

    for (int i = xElements.Count - 1; i > -1; i--) 
    { 
     xElements[i].Remove(); 
    } 
} 
+0

+1如果您使用的是.Net 3.5的理想情況 – 2009-10-09 18:08:45

+0

第一個代碼片段適用於我。好的解決方案+1 – 2010-04-21 09:55:55

+0

請注意,每個Remove()都會從第一個孩子開始遍歷子元素的內部鏈接列表,因此每個刪除的計算複雜度爲O(N)。是否有O(1)方法去除元素? – redcalx 2014-11-26 11:39:55

1

在循環邏輯之前創建一個集合,將要刪除的元素添加到新集合中,然後在新集合中的每個元素上調用items.Remove。

+0

這應該工作。我記得這樣做。我的答案可能不好。我記得如果你對列表或其他東西進行了修改,那麼使用for是一個好主意,但是如果你只是循環而不做任何修改,那麼foreach就沒有問題。它是否正確? – Xaisoft 2009-10-07 16:55:13

1

嘗試沒有而不是foreach。