Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

C# หา Common Elements ระหว่างสอง List (Intersect)

การหา **Common Elements** (สมาชิกร่วม) ระหว่างสอง List ใน C# ทำได้ง่ายด้วย LINQ Method Intersect() ซึ่งคืนค่า Set Intersection (ไม่ซ้ำกัน) โดย Default ใช้ Default Equality Comparer

Syntax

var common = list1.Intersect(list2);  // คืน IEnumerable

ตัวอย่างพื้นฐาน

using System;
using System.Linq;
using System.Collections.Generic;

namespace Demo {
    class Program {
        static void Main(string[] args) {
            List list1 = new List { 40, 20, 60, 3, 55 };
            List list2 = new List { 20, 70, 55, 80 };
            
            Console.WriteLine("Common elements:");
            foreach (int value in list1.Intersect(list2)) {
                Console.WriteLine(value);
            }
        }
    }
}

ผลลัพธ์

Common elements:
20
55

รายละเอียดการทำงาน

  • Set Operation: คืนค่า Unique Values เท่านั้น (Duplicates ถูกลบ)
  • Order Preserved: รักษาลำดับจาก List แรก (list1)
  • Deferred Execution: Query ไม่รันทันที รันตอน Iterate (foreach, ToList)
  • Equality Comparer: ใช้ EqualityComparer<T>.Default (สำหรับ Custom Class ต้อง Implement IEquatable<T> หรือ Override Equals/GetHashCode)

ตัวอย่างขั้นสูง

1. กับ Custom Class (ต้อง Implement IEquatable)

public class Product : IEquatable {
    public int Id { get; set; }
    public string Name { get; set; }
    
    public bool Equals(Product other) {
        return other != null && Id == other.Id;
    }
    
    public override bool Equals(object obj) => Equals(obj as Product);
    public override int GetHashCode() => Id.GetHashCode();
}

var list1 = new List { new Product { Id = 1 }, new Product { Id = 2 } };
var list2 = new List { new Product { Id = 2 }, new Product { Id = 3 } };

var common = list1.Intersect(list2);  // Product Id=2

2. ใช้ Custom Comparer

var common = list1.Intersect(list2, new ProductNameComparer());

public class ProductNameComparer : IEqualityComparer {
    public bool Equals(Product x, Product y) => x?.Name == y?.Name;
    public int GetHashCode(Product obj) => obj?.Name?.GetHashCode() ?? 0;
}

3. IntersectWith (Mutable - แก้ไข List ต้นฉบับ)

var list1 = new List { 1, 2, 3, 4, 5 };
var list2 = new List { 3, 4, 5, 6, 7 };

list1.IntersectWith(list2);  // list1 กลายเป็น { 3, 4, 5 } - แก้ไข In-place
// ต้องใช้ using System.Collections.Generic; และ List ต้องเป็น HashSet หรือ SortedSet
// จริงๆ List ไม่มี IntersectWith - ต้อง Convert เป็น HashSet ก่อน

4. เก็บ Duplicate ด้วย (Intersect แบบเก็บซ้ำ)

// Intersect มาตรฐาน: {1,2,2,3} ∩ {2,2,4} = {2}
// ถ้าต้องการเก็บ Duplicate ตามจำนวนน้อยที่สุด:
var list1 = new List { 1, 2, 2, 3 };
var list2 = new List { 2, 2, 4 };

var commonWithDuplicates = list1
    .GroupBy(x => x)
    .Join(list2.GroupBy(x => x), 
          g => g.Key, g => g.Key,
          (g1, g2) => g1.Take(Math.Min(g1.Count(), g2.Count())))
    .SelectMany(x => x);
// Result: {2, 2}

Related Set Operations

Operation Method คำอธิบาย
Intersection Intersect สมาชิกร่วม (A ∩ B)
Union Union รวมทั้งหมด ไม่ซ้ำ (A ∪ B)
Difference Except อยู่ใน A แต่ไม่อยู่ใน B (A - B)
Symmetric Difference Union + Except อยู่ในอันใดอันหนึ่งแต่ไม่ใช่ทั้งคู่

Performance

  • Time: O(n + m) - ใช้ HashSet ภายใน
  • Space: O(min(n, m)) - เก็บ HashSet ของ List ที่เล็กกว่า
  • เร็วกว่า Nested Loop (O(n×m)) มากสำหรับ List ใหญ่