2012-01-26 26 views
6

Mam listę z biblioteki kolekcji .NET i chcę usunąć pojedynczy element. Niestety, nie mogę go znaleźć, porównując bezpośrednio z innym obiektem.Usuwanie elementu z listy o predykacie

Obawiam się, że użycie FindIndex i RemoveAt spowoduje wielokrotne przechodzenie z listy.

nie wiem jak używać rachmistrzów do usunięcia elementów, które mogłyby inaczej pracował.

RemoveAll robi to, co muszę, ale nie zatrzyma się po jeden element zostanie znaleziony.

Pomysły?

+0

Czy możesz pokazać przykładowy kod? –

+0

Pytania są oznaczone 'linked-list', ale opis sugeruje' List '. Który to jest? – Ani

+0

Jakiego typu jest twoja lista? – Strillo

Odpowiedz

1

EDIT: Teraz OP zmieniła użyć LinkedList<T>, łatwo dać odpowiedź, która tylko iteracje tak dalece jak to ma się do:

public static void RemoveFirst<T>(LinkedList<T> list, Predicate<T> predicate) 
{ 
    var node = list.First; 
    while (node != null) 
    { 
     if (predicate(node.Value)) 
     { 
      list.Remove(node); 
      return; 
     } 
     node = node.Next; 
    } 
} 
+0

Szukam tylko usunięcia jednego elementu. – Steinbitglis

+0

@Steinbitglis: Czy będzie wiele wartości zgodnych z predykatem? I jakiej listy używasz? –

+0

@Steinbitglis: Edytowany w celu pokazania, jak można użyć efektu ubocznego do użycia 'RemoveAll'. –

2

Jeśli chcesz usunąć tylko pierwszy elementu który odpowiada predykat można wykorzystać następujący (przykład):

List<int> list = new List<int>(); 
list.Remove(list.FirstOrDefault(x => x = 10)); 

gdzie (x => x = 10) jest oczywiście twój orzeczenie o pasujące przedmioty.

+0

Wymaga to dwukrotnego wyliczenia listy. Raz, aby znaleźć pasujący przedmiot. Raz, aby znaleźć ten przedmiot ponownie w 'Remove'. –

+1

To prawda, że ​​użycie narzędzia RemoveAt jest bardziej wydajne. – Strillo

10

List<T> ma FindIndex sposób, że przyjmuje się orzeczenie

int index = words.FindIndex(s => s.StartsWith("x")); 
words.RemoveAt(index); 

Usuwa pierwszego słowa rozpoczynające "X". Zakłada się, że w tym przykładzie words jest List<string>.

+0

Jeśli lista ma indeks indeksu czasu stałego, myślę, że będzie dobrze. Martwiłem się, że RemoveAt również przejdzie tę listę. – Steinbitglis

+1

@Steinbitglis: To operacja O (n), ponieważ musi kopiować wszystko. Czy rzeczywiście * chcesz * połączoną listę? –

+0

Cóż, mam bardzo mało elementów, które ciągle przychodzą i odchodzą.Myślę, że przynajmniej hashtable byłoby głupie. Nie widzę żadnych problemów z połączonymi listami, poza tą pozornie banalną optymalizacją, której nie mogę zrozumieć. – Steinbitglis