0Pricing
C# Academy · บทเรียน

IComparer สำหรับการเรียงลำดับแบบกำหนดเอง

จัดเตรียมลำดับทางเลือกด้วยตัวเปรียบเทียบ

IComparer สำหรับการเรียงลำดับแบบกำหนดเอง เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

การเรียงลำดับหลายรูปแบบ

ชนิดข้อมูลหนึ่งชนิดมีลำดับตามธรรมชาติเพียงลำดับเดียวผ่าน IComparable<T> หากต้องการเรียงข้อมูลชุดเดียวกันด้วยวิธีอื่น ให้ส่ง IComparer<T> หรือตัวแทน Comparison<T> ณ จุดเรียกใช้

การนำ IComparer<T> ไปใช้

IComparer<T> เป็นออบเจ็กต์แยกต่างหากที่มีเมธอด Compare(x, y) โดยใช้ข้อตกลงค่าลบ ศูนย์ และค่าบวกแบบเดียวกับ CompareTo

using System;
using System.Collections.Generic;

public class Person
{
    public string Name;
    public int Age;
    public Person(string name, int age) { Name = name; Age = age; }
    public override string ToString() => Name + "(" + Age + ")";
}

public class ByName : IComparer<Person>
{
    public int Compare(Person x, Person y)
        => string.Compare(x.Name, y.Name, StringComparison.Ordinal);
}

public class Program
{
    public static void Main()
    {
        var people = new List<Person> { new Person("Zoe", 1), new Person("Ann", 2) };
        people.Sort(new ByName());
        Console.WriteLine(string.Join(", ", people));
    }
}

ตัวเปรียบเทียบหลายตัวสำหรับชนิดข้อมูลเดียว

คุณสามารถกำหนดตัวเปรียบเทียบหลายตัวและเลือกใช้ตัวใดตัวหนึ่งในการเรียงลำดับแต่ละครั้งได้ ในที่นี้ บุคคลกลุ่มเดียวกันสามารถเรียงตามชื่อหรือตามอายุได้ตามต้องการ

using System;
using System.Collections.Generic;

public class Person
{
    public string Name;
    public int Age;
    public Person(string name, int age) { Name = name; Age = age; }
    public override string ToString() => Name + "(" + Age + ")";
}

public class ByAge : IComparer<Person>
{
    public int Compare(Person x, Person y) => x.Age.CompareTo(y.Age);
}

public class Program
{
    public static void Main()
    {
        var people = new List<Person> { new Person("Ann", 40), new Person("Bo", 20) };
        people.Sort(new ByAge());
        Console.WriteLine(string.Join(", ", people));
    }
}

ตัวแทน Comparison<T>

สำหรับการเรียงลำดับแบบใช้ครั้งเดียว ตัวแทน Comparison<T> ซึ่งมักเป็นแลมบ์ดา จะกระชับกว่าการสร้างคลาสทั้งคลาส และ List.Sort รับตัวแทนนี้ได้โดยตรง

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var words = new List<string> { "banana", "fig", "apple" };
        // Sort by length using a Comparison<string> lambda
        words.Sort((a, b) => a.Length.CompareTo(b.Length));
        Console.WriteLine(string.Join(", ", words));
    }
}

เรียงจากมากไปน้อยด้วยตัวเปรียบเทียบ

กลับลำดับโดยสลับตัวถูกดำเนินการภายใน Compare วิธีนี้ทำให้เรียงจากมากไปน้อยได้โดยไม่ต้องแก้ไขชนิดข้อมูลเอง

using System;
using System.Collections.Generic;

public class DescendingInt : IComparer<int>
{
    public int Compare(int x, int y) => y.CompareTo(x);
}

public class Program
{
    public static void Main()
    {
        var nums = new List<int> { 3, 1, 4, 1, 5 };
        nums.Sort(new DescendingInt());
        Console.WriteLine(string.Join(", ", nums));
    }
}

ตัวเปรียบเทียบใน OrderBy

LINQ OrderBy รับ IComparer<TKey> เป็นอาร์กิวเมนต์ตัวที่สอง ทำให้คุณกำหนดวิธีเปรียบเทียบคีย์ที่เลือกได้เอง

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

public class CaseInsensitive : IComparer<string>
{
    public int Compare(string x, string y)
        => string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
}

public class Program
{
    public static void Main()
    {
        var names = new[] { "bob", "Alice", "carol" };
        foreach (var n in names.OrderBy(x => x, new CaseInsensitive()))
            Console.WriteLine(n);
    }
}

การเปรียบเทียบหลายคีย์

ตัวเปรียบเทียบสามารถเรียงตามหลายคีย์ตามลำดับความสำคัญได้ ให้คำนวณคีย์แรกก่อน และหากค่าเท่ากันจึงเลื่อนไปพิจารณาคีย์ถัดไป

using System;
using System.Collections.Generic;

public class Employee
{
    public string Dept;
    public int Salary;
    public Employee(string dept, int salary) { Dept = dept; Salary = salary; }
    public override string ToString() => Dept + ":" + Salary;
}

public class ByDeptThenSalary : IComparer<Employee>
{
    public int Compare(Employee x, Employee y)
    {
        int byDept = string.Compare(x.Dept, y.Dept, StringComparison.Ordinal);
        return byDept != 0 ? byDept : x.Salary.CompareTo(y.Salary);
    }
}

public class Program
{
    public static void Main()
    {
        var staff = new List<Employee>
        {
            new Employee("IT", 50), new Employee("HR", 40), new Employee("IT", 30)
        };
        staff.Sort(new ByDeptThenSalary());
        Console.WriteLine(string.Join(", ", staff));
    }
}

ทางลัดด้วย Comparer.Create

Comparer<T>.Create สร้าง IComparer<T> จากแลมบ์ดา โดยผสานความกระชับของตัวแทนเข้ากับ API ของอินเทอร์เฟซที่ต้องใช้ตัวเปรียบเทียบ

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var byLengthDesc = Comparer<string>.Create((a, b) => b.Length.CompareTo(a.Length));
        var words = new List<string> { "hi", "hello", "hey" };
        words.Sort(byLengthDesc);
        Console.WriteLine(string.Join(", ", words));
    }
}

นำตัวเปรียบเทียบกลับมาใช้กับคอลเลกชันต่าง ๆ

อินสแตนซ์ของตัวเปรียบเทียบเพียงตัวเดียวสามารถใช้ควบคุมการเรียงลำดับ การค้นหา และเซตที่เรียงลำดับได้ การกำหนดกฎการเรียงลำดับเพียงครั้งเดียวช่วยให้กฎสอดคล้องกันทุกแห่งที่นำไปใช้

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        IComparer<int> desc = Comparer<int>.Create((a, b) => b.CompareTo(a));
        var set = new SortedSet<int>(desc) { 1, 5, 3 };
        Console.WriteLine(string.Join(", ", set));
    }
}

การเลือกใช้ IComparable หรือ IComparer

ใช้ IComparable<T> สำหรับลำดับตามธรรมชาติเพียงลำดับเดียวที่ฝังอยู่ในชนิดข้อมูล ใช้ IComparer<T> หรือ Comparison<T> สำหรับลำดับทางเลือกหลายแบบที่ขึ้นอยู่กับบริบทและกำหนด ณ จุดเรียกใช้

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var nums = new List<int> { 5, 2, 8, 1 };
        nums.Sort(); // natural ascending (int is IComparable)
        Console.WriteLine(string.Join(", ", nums));
        nums.Sort((a, b) => b - a); // custom descending via delegate
        Console.WriteLine(string.Join(", ", nums));
    }
}

ลองทำด้วยตนเอง

เรียงรายการเดียวกันสามรูปแบบโดยใช้ตัวเปรียบเทียบและแลมบ์ดา โดยไม่ต้องแก้ไขชนิดข้อมูลของสมาชิกเลย

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var words = new List<string> { "pear", "fig", "apple", "kiwi" };

        words.Sort(); // natural alphabetical
        Console.WriteLine(string.Join(", ", words));

        words.Sort((a, b) => a.Length.CompareTo(b.Length)); // by length
        Console.WriteLine(string.Join(", ", words));

        words.Sort(Comparer<string>.Create((a, b) => b.CompareTo(a))); // reverse alphabetical
        Console.WriteLine(string.Join(", ", words));
    }
}

ตรวจสอบอย่างรวดเร็ว

เลือกนามธรรมสำหรับการจัดลำดับให้เหมาะสม

สรุปทบทวน

การเรียงลำดับแบบกำหนดเองใช้ตัวเปรียบเทียบที่ส่งเข้ามา ณ จุดเรียกใช้

  • IComparer<T> นำ Compare(x, y) ไปใช้โดยใช้ข้อตกลงค่าลบ ศูนย์ และค่าบวก
  • ตัวแทน Comparison<T> และแลมบ์ดาเหมาะกับการเรียงลำดับแบบใช้ครั้งเดียว
  • Comparer<T>.Create เชื่อมแลมบ์ดาเข้ากับอินเทอร์เฟซ
  • ใช้ IComparable สำหรับลำดับตามธรรมชาติ และใช้ตัวเปรียบเทียบสำหรับลำดับทางเลือก

คำถามที่พบบ่อย

บทเรียน “IComparer สำหรับการเรียงลำดับแบบกำหนดเอง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “IComparer สำหรับการเรียงลำดับแบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “IComparer สำหรับการเรียงลำดับแบบกำหนดเอง”

จัดเตรียมลำดับทางเลือกด้วยตัวเปรียบเทียบ คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “IComparer สำหรับการเรียงลำดับแบบกำหนดเอง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การนำ IEquatable ไปใช้
  2. การเขียนทับ GetHashCode
  3. การนำ IComparable ไปใช้
  4. IComparer สำหรับการเรียงลำดับแบบกำหนดเอง
← กลับไปที่ C# Academy