Jak za jednym razem usunąć wszystkie puste elementy z ogólnej listy?


112

Czy istnieje domyślna metoda zdefiniowana w .Net dla C #, aby usunąć wszystkie elementy z listy, które są null?

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

Powiedzmy, że niektóre parametry są null; Nie mogę wiedzieć z góry i chcę je usunąć z mojej listy, aby zawierała tylko parametry, które nie są zerowe.

Odpowiedzi:


225

Prawdopodobnie będziesz potrzebować następujących.

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};
parameterList.RemoveAll(item => item == null);

4
Tak, to jest to samo, co moja odpowiedź, ale używam nowszej składni lambda C # 3.
Mark Bell

@Mark: Widziałem opublikowane sekundy i człowieku było blisko (32, 33 i 34). ;)
Lance

1
Tak ... cóż, twoja odpowiedź działa nawet w starszych wersjach, więc +1! No więc, ha! ; Þ
Lance

43

Nie znam żadnej wbudowanej metody, ale możesz po prostu użyć linq:

parameterList = parameterList.Where(x => x != null).ToList();

5
Należy tego unikać, jeśli parameterListjest już Listą, ponieważ spowoduje to niepotrzebne utworzenie nowej kopii. W takim przypadku użyj RemoveAllmetody tak, jak sugerują inni.
Nick

Jest to prawdopodobnie najlepsza opcja, jeśli kolekcja to Array.
Andrew,

25

Metoda RemoveAll powinna załatwić sprawę:

parameterList.RemoveAll(delegate (object o) { return o == null; });

Dlaczego nie skorzystać z lambdy?
Mike de Klerk

12
To jest odpowiedź sprzed czterech lat. W tamtym czasie C # 3 był stosunkowo nowy i nadal używałem C # 2 na co dzień. Składnia lambda jest teraz właściwą drogą; jednak jest to nadal działająca odpowiedź, więc zostawiłem ją tutaj dla każdego, kto nie może używać nowszej składni (z jakiegokolwiek powodu).
Mark Bell

2
Nie wiedziałem, że składnia lambda pojawiła się później. Dziękuję za wyjaśnienie! Bez wątpienia jest to ważne.
Mike de Klerk

8

Metoda OfType()pominie wartości null:

List<EmailParameterClass> parameterList =
    new List<EmailParameterClass>{param1, param2, param3...};

IList<EmailParameterClass> parameterList_notnull = 
    parameterList.OfType<EmailParameterClass>();

W pewnym sensie jest to dobre podejście, ale zaskakuje dewelopera, który po prostu myśli, że OfTypewybiera obiekty określonego typu, nie myśląc, że nie będzie zawierał nullwartości ... Więc jestem trochę zmęczony wprowadzaniem tego do mojego własnego kodu.

@ BjörnAliGöransson Zgoda. To ciekawe rozwiązanie, ale nie „czyta” zbyt jasno. Używanie .RemoveAll z lambdą nadal utrzymuje wszystko w jednym wierszu, jednocześnie pokazując, co chciał osiągnąć programista, który to napisał. Może to jednak być przydatne, jeśli warto skorzystać z szybkości.
MattD,

4
List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

parameterList = parameterList.Where(param => param != null).ToList();

2

Łatwo i bez LINQ:

while (parameterList.Remove(null)) {};

Ta metoda jest w Listklasie tuż obok RemoveAll, więc polecam ją dla jasności. Jeśli wydajność okazała się kluczowa, możesz zastosować to podejście (chociaż usunąłbym nawiasy i prawdopodobnie dodałbym komentarz dla nieświadomych programistów).
Andrew,

1
@Andrew: zgodnie z MSDN RemoveAll nie przyjmuje wartości null. Myślę, że też to przetestowałem. Komentarz ma jednak sens.
Tobias Knauss,

1
RemoveAllotrzymała Predicate, więc powinieneś użyć RemoveAll(x => x == null), jak widać w zaakceptowanej odpowiedzi Marka Bella.
Andrew,

1

Jest jeszcze jedna prosta i elegancka opcja:

parameters.OfType<EmailParameterClass>();

Spowoduje to usunięcie wszystkich elementów, które nie są typu, EmailParameterClassco oczywiście odfiltruje wszelkie elementy typu null.

Oto test:

class Test { }
class Program
{
    static void Main(string[] args)
    {
        var list = new List<Test>();
        list.Add(null);
        Console.WriteLine(list.OfType<Test>().Count());// 0
        list.Add(new Test());
        Console.WriteLine(list.OfType<Test>().Count());// 1
        Test test = null;
        list.Add(test);
        Console.WriteLine(list.OfType<Test>().Count());// 1
        Console.ReadKey();
    }
}

Czy to zadziała? nie będzie odwołaniami do elementu nadal typu EmailParameterClassi będzie mieć tylko wartość równą null?
derHugo

Na pewno tak i dodałem tester dla twojej rozrywki.
Ryan Naccarato
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.