C #: Почему LinkedList не имеет метода RemoveAll, который принимает предикат? - PullRequest
7 голосов
/ 08 февраля 2010

У меня есть LinkedList узлов, каждый из которых хранит LinkedList ребер. Я хотел сделать что-то вроде

nodes.RemoveAll(n => n.edges.Count == 0)

Но без RemoveAll это происходит. Я не понимаю, почему у него его нет, так как у других коллекций. Это также должно было бы выполнять итерацию по всем элементам и удалять только один за раз из того, что я понимаю, что не было бы плохо для производительности связанного списка.

Теперь я должен сделать это вместо:

for (LinkedListNode<MyNode> n2 = nodes.First; n2 != null; )
{
    LinkedListNode<MyNode> temp = n2.Next;
    if (n2.Value.edges.Count == 0)
        nodes.Remove(n2);
    n2 = temp;
}

Хотя это работает, оно делает вещи более сложными, чем они есть.

1 Ответ

9 голосов
/ 08 февраля 2010

Я не могу сказать, почему этот метод не существует. Казалось бы, полезный способ иметь. Вы можете добавить его самостоятельно, используя метод расширения. Вот моя (вероятно, неудачная и не проверенная) попытка сделать это:

public static class LinkedListExtensions
{
    public static void RemoveAll<T>(this LinkedList<T> linkedList,
                                    Func<T, bool> predicate)
    {
        for (LinkedListNode<T> node = linkedList.First; node != null; )
        {
            LinkedListNode<T> next = node.Next;
            if (predicate(node.Value))
                linkedList.Remove(node);
            node = next;
        }
    }
}

Тогда это работает:

nodes.RemoveAll(n => n.edges.Count == 0);

В качестве альтернативы вы можете инвертировать критерий, чтобы выбрать элементы, которые хотите сохранить, и создать из них новый LinkedList:

nodes = new LinkedList<MyNode>(nodes.Where(n => n.edges.Count != 0));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...