Làm thế nào để loại bỏ tất cả các phần tử rỗng bên trong một danh sách chung trong một lần?


112

Có phương pháp mặc định nào được định nghĩa trong .Net cho C # để loại bỏ tất cả các phần tử trong danh sách nullkhông?

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

Giả sử một số tham số là null; Tôi không thể biết trước và tôi muốn xóa chúng khỏi danh sách của mình để nó chỉ chứa các tham số không rỗng.

Câu trả lời:


225

Có thể bạn sẽ muốn những thứ sau đây.

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

4
Đúng, đây giống như câu trả lời của tôi nhưng sử dụng cú pháp lambda C # 3 mới hơn.
Mark Bell

@Mark: Tôi đã xem những giây được đăng và người đàn ông đó là gần (32, 33 và 34). ;)
Lance

1
Vâng ... câu trả lời của bạn hoạt động ngay cả trong các phiên bản cũ hơn, vì vậy hãy +1! Vì vậy, đó, ha! ; Þ
Lance

43

Tôi không biết về bất kỳ phương pháp tích hợp sẵn nào, nhưng bạn có thể sử dụng linq:

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

5
Điều này nên tránh nếu parameterListđã là một Danh sách, vì nó sẽ tạo ra một bản sao mới một cách không cần thiết. Trong trường hợp đó, hãy sử dụng RemoveAllphương pháp như những người khác gợi ý.
Nick

Đây có lẽ là lựa chọn tốt nhất nếu bộ sưu tập là một Array.
Andrew

25

Phương thức RemoveAll sẽ thực hiện thủ thuật:

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

Tại sao không sử dụng lambda?
Mike de Klerk

12
Đây là một câu trả lời cũ bốn năm. Vào thời điểm đó C # 3 còn tương đối mới, và tôi vẫn đang sử dụng C # 2 hàng ngày. Cú pháp lambda bây giờ là cách để đi; tuy nhiên, đây vẫn là một câu trả lời hoạt động, vì vậy tôi đã để nó ở đây cho bất kỳ ai không thể sử dụng cú pháp mới hơn (vì bất kỳ lý do gì).
Mark Bell

2
Tôi không biết rằng cú pháp lambda đã xuất hiện sau đó. Cảm ơn bạn đã giải thích của bạn! Không nghi ngờ gì nữa, nó là hợp lệ.
Mike de Klerk

8

Phương thức OfType()sẽ bỏ qua các giá trị null:

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

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

Theo một cách nào đó, đây là một cách tiếp cận tốt, nhưng nó mang lại sự ngạc nhiên cho nhà phát triển, những người chỉ nghĩ rằng OfTypechọn các đối tượng thuộc một loại nhất định, không nghĩ rằng nó sẽ không bao gồm nullcác giá trị ... Vì vậy, tôi hơi mệt khi giới thiệu điều này vào mã của riêng tôi.

@ BjörnAliGöransson Đồng ý. Đó là một giải pháp thú vị, nhưng nó không "đọc" rõ ràng lắm. Sử dụng .RemoveAll với lambda vẫn giữ mọi thứ trên một dòng trong khi làm cho nó thực sự rõ ràng về những gì nhà phát triển đã viết nó đang cố gắng đạt được. Tuy nhiên, điều này có thể hữu ích nếu có lợi ích về tốc độ đáng giá.
MattD

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

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

2

Dễ dàng và không có LINQ:

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

Phương pháp đó nằm trong Listlớp ngay bên cạnh RemoveAll, vì vậy tôi khuyên bạn nên dùng phương pháp đó để rõ ràng. Nếu hiệu suất xảy ra là rất quan trọng, thì bạn có thể thực hiện theo cách tiếp cận này (mặc dù tôi muốn xóa dấu ngoặc và có thể thêm nhận xét cho các nhà phát triển không biết).
Andrew

1
@Andrew: theo MSDN, RemoveAll không lấy null. Tôi nghĩ rằng tôi cũng đã thử nghiệm điều đó. Một nhận xét có ý nghĩa mặc dù.
Tobias Knauss

1
RemoveAllnhận được Predicate, vì vậy bạn nên sử dụng RemoveAll(x => x == null), như đã thấy trong câu trả lời được chấp nhận và Mark Bell.
Andrew

1

Có một tùy chọn đơn giản và thanh lịch khác:

parameters.OfType<EmailParameterClass>();

Thao tác này sẽ loại bỏ tất cả các phần tử không thuộc loại EmailParameterClass, rõ ràng sẽ lọc ra bất kỳ phần tử nào cùng loại null.

Đây là một bài kiểm tra:

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();
    }
}

cái này sẽ hoạt động chứ? sẽ không phải là các tham chiếu phần tử vẫn thuộc loại EmailParameterClassvà chỉ có giá trị bằng null?
derHugo

Nó chắc chắn sẽ và tôi đã thêm người thử nghiệm để bạn giải trí.
Ryan Naccarato,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.