LinkedList<T>(2.0):迭代删除项目

6

我需要遍历一个 LinkedList<T>(在 .NET 2.0 中),并根据给定的条件删除所有项目。在 Java 下很容易实现,因为我可以执行以下操作:

Iterator<E> i = list.iterator();
while (i.hasNext()) {
    E e = i.next();
    if (e == x) {
        // Found, so move it to the front,
        i.remove();
        list.addFirst(x);
        // Return it
        return x;
    }
}

很遗憾,在.NET中的 IEnumerator<T> 行为(相当于 Iterator<E>)中没有 remove 方法来从集合中移除当前元素。此外,在 LinkedList<T> 中没有办法访问给定索引处的元素,必须通过从后往前迭代来完成该任务。
你有什么好主意吗?非常感谢!

3
为什么这是一个社区维基页面?这不是主观的事情 - 这里有一个明确的答案。 - Reed Copsey
4个回答

14
这将在通过链表的一次循环中删除所有符合条件的节点。
LinkedListNode<E> node = list.First;

while (node != null)
{
    var next = node.Next;
    if (node.Value == x) {
        list.Remove(e);
    }
    node = next;
}

我相信这就是你想要尝试的...你还把节点添加回了列表开头(所以你的Java代码没有删除所有节点,而是将第一个匹配项移动到了列表的开头)。采用这种方法很容易实现这一点。


3
应该是list.Remove(node)吧? - Maksim Kneller

1

在C#中实际上要容易得多。

function PlaceAtHead(<T> x)
{
   list.Remove(x);
   list.AddFirst(x);
   return x;
}

我还没有尝试过,但我相信这会引发一个异常,因为枚举器是开放的... - Antonello
这段代码与Antonello的代码片段完全相同。您不能在枚举过程中删除项目,但是.Net允许您直接删除项目而无需枚举查找它们。从任何一种.Net列表中删除项的标准解决方案是建立一个要删除项的第二个列表,并在枚举器完成后将它们删除,这只是简化了该过程。 - Kris Erickson
+1,适用于原始帖子的示例和其他情况,如果您先找到要删除的项,则会起作用。 - Meta-Knight

1

Reed Copsey的回答中,只需添加一个谓词:

    public static T MoveAheadAndReturn<T>(LinkedList<T> ll, Predicate<T> pred)
    {
        if (ll == null)
            throw new ArgumentNullException("ll");
        if (pred == null)
            throw new ArgumentNullException("pred");


        LinkedListNode<T> node = ll.First;
        T value = default(T);

        while (node != null)
        {
            value = node.Value;
            if (pred(value))
            {
                ll.Remove(node);
                ll.AddFirst(node);
                break;
            }
            node = node.Next;
        }

        return value;
    }

1
一个丑陋的选择是迭代遍历列表,找到所有适用项并将它们存储在列表中。然后迭代遍历第二个列表,并在LinkedList上调用remove...
我希望有其他更优雅的解决方案 :)

这也是我想的,但是除了优雅之外,在每种情况下它都不能工作,因为列表中的2个节点可能相等... - Antonello
我在下面放了一个一遍过的版本,它也会处理重复项。它基于使用 LinkedList<T>.Remove(LinkedListNode<T>)。 - Reed Copsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接