2012-01-02 54 views
3

删除对象在Java中,我可以重复采集和使用方法Iterator.remove()http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Iterator.html#remove()的Java模拟,从集合

这是非常handly和自然从中删除某些对象。就像你正在冰箱里寻找食物,扔掉过期日期的食物。如何在C#中做同样的事情?

我想iterateclean-up集合在同一个循环。

有几个相关的问题,例如How to iterate and update a list但我仍然无法找到此操作的精确复制在C#

回答

7

如果您使用的是List<T>,则有一个方便的方法来执行此操作(RemoveAll),它将删除与谓词(表示为委托)相匹配的所有元素。例如:

List<Person> people = ...; 
people.RemoveAll(person => person.Age < 18); 
// Just the adults left now... 

这比向后迭代IMO更简单。

当然,如果你乐于创造一个新名单相反,你可以使用LINQ:

var adults = people.Where(person => person.Age >= 18).ToList(); 
+0

我想明确使用'for'或'foreach'循环,因为我想对每个项目执行一些操作。在此过程中,我想删除过期的商品。你的建议只会删除过时的项目,但它不允许我在其他项目上工作。 – javapowered 2012-01-02 21:14:07

+0

@javapowered:当然它。谓词是为每个项目调用的,其返回值控制着项目是否被移除。您可以在谓词中进行工作,唯一不能做的就是替换项目(但可以更改将影响集合的引用类型的成员)。由于您无法在移除的项目上工作,因此要求您返回以便导致移除似乎不是问题。 – 2012-01-02 21:16:11

+0

@javapowered,另一个例子'var list = new List (){1,2,3,4,5,6};名单。RemoveAll(i => i%2 == 0);' – 2012-01-02 21:18:15

2

在C#中,你可以使用一个for循环遍历集合,并在它删除的项目 - 这将为IList<T>收藏。

为了安全,你应该向后

for(int i = coll.Count - 1; i >= 0; i--) 
{ 
    if(coll[i] == something) 
    { 
    coll.RemoveAt(i); 
    } 
} 

迭代如果你可以使用LINQ,看RemoveAll作为乔恩斯基特建议。这将允许您从列表中删除所有项目而无需迭代,但只需提供一个谓词。

+0

这可能会导致异常。 – 2012-01-02 20:42:08

+0

@ DanielA.White - 回答更新。 – Oded 2012-01-02 20:45:42

2

只需使用for循环向后

List<string> collection = new List<String> { "Hello", "World", "One", "Two", "Three"}; 
collection.Dump("Original List"); 
for(int i = collection.Count-1; i>=0; i--) 
{ 
    if (collection[i] == "One"){ 
     collection.RemoveAt(i); 
    } 
} 
collection.Dump("After deleting"); 

计数顺便说一句,这是来自Knuth books

编辑一个典型的例子:这个例子很好地工作在LINQPad - 用于演示的目的。转储()在VS中不起作用。

+1

只是想很明显,这里的关键是通过索引中删除,并在反向工作不干扰其余要搜索的列表的一部分。 – lincolnk 2012-01-02 20:48:45

+1

这是一个解决方案,但不好。对于那些东西,Jave有很好的'iterator',但是在C#中,我必须手动迭代... – javapowered 2012-01-02 21:17:50