2011-11-19 52 views
1

这就是我从List中删除项目的方法。这是正确的方式吗?有没有更清洁/更快的方式来实现这一点。从列表中删除项目<Type>

List<ItemClass> itemsToErase = new List<ItemClass>(); 
foreach(ItemClass itm in DS) 
{ 
     if(itm.ToBeRemoved) 
      itemsToErase .Add(itm); 
} 
foreach(ItemClass eraseItem in itemsToErase) 
{ 
     DS.Remove(eraseItem); 
}  

编辑:DS的类型为List<ItemClass>

编辑:多了一个疑问。如果DS是LinkedList<ItemClass>,该怎么办?这没有RemoveAll()

+0

是的,这是'名单' – devnull

回答

2

List.RemoveAll()它需要一个委托,您可以添加您的比较功能。

例如为:

List<ItemClass> itemsToErase = new List<ItemClass>(); 
itemsToErase.RemoveAll(itm => itm.ToBeRemoved); 
+1

+1:先用回复的removeAll 。 – x0n

1

不是真的,该逻辑是一样的,不管你怎么做。您无法同时迭代和修改集合。它看起来吸尘器LINQ:

var list = new List<int> { 1, 2, 3, 4, 5 }; 
var except = new List<int> { 3, 4 }; 
var result = list.Except(except); 

希望这有助于。

编辑: 即使 list.RemoveAll(...)必须在内部维护两个列表才能执行此操作。

edit2:其实svick是正确的;在查看实现之后,RemoveAll是最快的。

+0

有趣。 LINQ更干净,但不是更快? – devnull

+0

除''结果'不再是'List'以外。如果你想这样做,你将不得不调用'ToList()',如果列表很大,可能会太多复制。 – svick

+0

而'RemoveAll()'不必维护两个列表。这一切都在一个列表中完成。 – svick

1

您可以使用the RemoveAll() method

DS.RemoveAll(x => x.ToBeRemoved); 

这是一个O(n)的操作,你的代码是O(n^2)。

0

使用这种方法

DS.RemoveAll(x => x.ToBeRemoved); 
1

这种方法避免了原单列出了很多副本,但具有更大的内存消耗。

List<ItemClass> newList = new List<ItemClass>(originalList.Count); 

foreach(var item in originalList) { 
    if (!item.ToBeRemoved) 
     newList.Add(item); 
} 

originalList = newList; 
+0

+1。这可能是最快的方法。另一个快速但更复杂的方法是,使用列表索引器重新排列保留的项目,最后使用RemoveRange方法截断列表。 –

0

你的代码是一个常见的问题解决方案,很好。特别是如果只有少数项目需要移除。
正如其他人所建议的,您也可以创建一个包含您想保留的项目的新列表,然后丢弃旧列表。如果大多数项目都将被删除并且只保留一小部分,这会更好。 选择这些方法时,请记住两者都需要分配一个新的列表对象。这额外的内存分配可能不是问题,但可能是,取决于其他代码正在做什么。
正如其他人所说,还有RemoveAll方法。这就是我会用到的,它清晰,清晰,并且与使用列表的任何东西一样高效。
最后一个选项是使用索引循环访问集合。例如。
(对不起,VB,我用它往往比C#,并没有想通过得到的语法错误混淆)

Dim i as Integer 
Do While i<DS.Count 
If DS.Item(i).ToBeRemoved Then 
DS.RemoveAt(i) 
Else 
i+=1 
End If 
Loop