Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Xóa phần tử List thỏa mãn điều kiện predicate trong C#

Phương thức RemoveAll(Predicate<T> match) của List<T> xóa tất cả các phần tử thỏa mãn điều kiện được định nghĩa bởi delegate Predicate<T>. Phương thức trả về số lượng phần tử đã xóa.

Ví dụ 1: Xóa tất cả phần tử bằng 500

using System;
using System.Collections.Generic;

public class Demo
{
    // Predicate: trả về true nếu phần tử cần xóa
    private static bool Is500(int i)
    {
        return (i == 500);
    }

    public static void Main(string[] args)
    {
        List<int> list = new List<int>();
        list.Add(100);
        list.Add(500);
        list.Add(300);
        list.Add(400);
        list.Add(500);
        list.Add(600);
        list.Add(500);

        Console.WriteLine("Các phần tử trong List...");
        foreach (int i in list)
        {
            Console.WriteLine(i);
        }

        Console.WriteLine();

        // Xóa tất cả phần tử = 500
        int removedCount = list.RemoveAll(Is500);

        Console.WriteLine("Số phần tử đã xóa: " + removedCount);
        Console.WriteLine("\nList sau khi xóa các phần tử 500...");
        foreach (int i in list)
        {
            Console.WriteLine(i);
        }
    }
}

Kết quả

Các phần tử trong List...
100
500
300
400
500
600
500

Số phần tử đã xóa: 3

List sau khi xóa các phần tử 500...
100
300
400
600

Ví dụ 2: Xóa phần tử chia hết cho 10 (Lambda expression)

using System;
using System.Collections.Generic;

public class Demo
{
    public static void Main(string[] args)
    {
        List<int> list = new List<int>();
        list.Add(100);
        list.Add(295);
        list.Add(355);
        list.Add(450);
        list.Add(550);

        Console.WriteLine("Các phần tử trong List...");
        foreach (int i in list)
        {
            Console.WriteLine(i);
        }

        Console.WriteLine();

        // Lambda expression: x => x % 10 == 0
        int removedCount = list.RemoveAll(x => x % 10 == 0);

        Console.WriteLine("Số phần tử đã xóa: " + removedCount);
        Console.WriteLine("\nList sau khi xóa các phần tử chia hết cho 10...");
        foreach (int i in list)
        {
            Console.WriteLine(i);
        }
    }
}

Kết quả

Các phần tử trong List...
100
295
355
450
550

Số phần tử đã xóa: 3

List sau khi xóa các phần tử chia hết cho 10...
295
355

Predicate<T> Delegate

// Định nghĩa
public delegate bool Predicate<in T>(T obj);

// Cách dùng:
// 1. Method group (có sẵn method)
list.RemoveAll(Is500);

// 2. Anonymous method (C# 2.0)
list.RemoveAll(delegate(int x) { return x == 500; });

// 3. Lambda expression (C# 3.0+) - KHUYẾN NGHỊ
list.RemoveAll(x => x == 500);
list.RemoveAll(x => x > 100 && x < 500);
list.RemoveAll(s => s.StartsWith("A") && s.Length > 5); // Với List<string>

Các ví dụ Predicate phổ biến

Điều kiện Lambda
Bằng giá trị x => x == value
Trong khoảng x => x >= min && x <= max
Chuỗi bắt đầu bằng s => s.StartsWith("prefix")
Chuỗi chứa s => s.Contains("text")
Null hoặc rỗng s => string.IsNullOrEmpty(s)
Object property p => p.Age > 18 && p.IsActive
Phức tạp x => ComplexCondition(x)

Hiệu năng và lưu ý

  • Phức tạp: O(n) - duyệt qua tất cả phần tử một lần
  • Trả về: int - số phần tử đã xóa
  • Thay đổi in-place (trên List gốc)
  • Giữ thứ tự các phần tử còn lại
  • Hiệu quả hơn nhiều so với vòng lặp xóa thủ công (tránh shift nhiều lần)

So sánh với các phương thức xóa khác

Phương thức Mô tả Trả về
Remove(T item) Xóa 1 lần xuất hiện đầu tiên bool
RemoveAt(int index) Xóa tại chỉ mục void
RemoveRange(int index, int count) Xóa dải phần tử void
RemoveAll(Predicate<T>) Xóa tất cả thỏa điều kiện int (số lượng)
Clear() Xóa tất cả void

Ví dụ với object phức tạp

class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public bool Discontinued { get; set; }
}

List<Product> products = GetProducts();

// Xóa sản phẩm ngừng bán
int removed = products.RemoveAll(p => p.Discontinued);

// Xóa sản phẩm giá > 1000
removed = products.RemoveAll(p => p.Price > 1000m);