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

Toán tử Union, Intersect, Except trong LINQ C#

Tổng quan 3 toán tử Set Operations

Toán tửMô tảKết quả
UnionHợp hai tập hợp, loại bỏ trùng lặpDistinct elements từ cả hai
IntersectGiao hai tập hợpPhần tử có trong CẢ HAI
ExceptHiệu hai tập hợpPhần tử chỉ có trong THỨ NHẤT

Ví dụ cơ bản với Array


using System;
using System.Linq;

class Program 
{
    static void Main() 
    {
        int[] set1 = { 1, 2, 3, 4 };
        int[] set2 = { 2, 4, 7 };
        
        // Union: 1, 2, 3, 4, 7
        var union = set1.Union(set2);
        
        // Intersect: 2, 4
        var intersect = set1.Intersect(set2);
        
        // Except (set1 - set2): 1, 3
        var except = set1.Except(set2);
        
        Console.WriteLine("Union: " + string.Join(", ", union));
        Console.WriteLine("Intersect: " + string.Join(", ", intersect));
        Console.WriteLine("Except: " + string.Join(", ", except));
    }
}

Kết quả

Union: 1, 2, 3, 4, 7
Intersect: 2, 4
Except: 1, 3

Ví dụ với Object Complex (Cần IEqualityComparer)


class Product 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

class ProductComparer : IEqualityComparer 
{
    public bool Equals(Product x, Product y) 
    {
        if (x is null || y is null) return false;
        return x.Id == y.Id; // So sánh theo Id
    }
    
    public int GetHashCode(Product obj) 
    {
        return obj.Id.GetHashCode();
    }
}

class Program 
{
    static void Main() 
    {
        var list1 = new List 
        {
            new Product { Id = 1, Name = "Laptop", Price = 1000 },
            new Product { Id = 2, Name = "Mouse", Price = 25 },
            new Product { Id = 3, Name = "Keyboard", Price = 75 }
        };
        
        var list2 = new List 
        {
            new Product { Id = 2, Name = "Mouse", Price = 25 },
            new Product { Id = 3, Name = "Keyboard Pro", Price = 120 },
            new Product { Id = 4, Name = "Monitor", Price = 300 }
        };
        
        var comparer = new ProductComparer();
        
        // Union: distinct by Id
        var union = list1.Union(list2, comparer);
        // Intersect: Id 2, 3
        var intersect = list1.Intersect(list2, comparer);
        // Except: Id 1 (chỉ có trong list1)
        var except = list1.Except(list2, comparer);
    }
}

Union vs Concat


var a = new[] { 1, 2, 3 };
var b = new[] { 3, 4, 5 };

// Union: Loại trùng lặp
a.Union(b);     // { 1, 2, 3, 4, 5 }

// Concat: Giữ trùng lặp
a.Concat(b);    // { 1, 2, 3, 3, 4, 5 }

Except vs Where Not Contains


// Except - Set based, hiệu quả hơn
var except = list1.Except(list2, comparer);

// Where + Contains - Chậm hơn cho collection lớn
var whereNotIn = list1.Where(x => !list2.Contains(x, comparer));

Distinct - Toán tử liên quan


// Loại bỏ trùng lặp trong một collection
var numbers = new[] { 1, 2, 2, 3, 3, 3, 4 };
var distinct = numbers.Distinct(); // { 1, 2, 3, 4 }

// Distinct với comparer
var distinctProducts = products.Distinct(new ProductComparer());

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

  • Union/Intersect/Except sử dụng HashSet nội bộ → O(n + m) average.
  • Yêu cầu GetHashCode() và Equals() được implement đúng (cho custom types).
  • Trả về IEnumerable<T> - deferred execution.
  • Giữ thứ tự xuất hiện của collection đầu tiên (stable).

Overload với IEqualityComparer


// Tất cả 3 toán tử đều có overload nhận comparer
source.Union(other, comparer);
source.Intersect(other, comparer);
source.Except(other, comparer);
source.Distinct(comparer);

Ứng dụng thực tế

  • Union: Gộp danh sách user từ nhiều nguồn, loại trùng.
  • Intersect: Tìm user có quyền truy cập CẢ HAI hệ thống.
  • Except: Tìm user đã xóa (có trong old list nhưng không có trong new list).
  • Distinct: Làm sạch dữ liệu nhập vào.