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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การนำ IEquatable ไปใช้
- การเขียนทับ GetHashCode
- การนำ IComparable ไปใช้
- IComparer สำหรับการเรียงลำดับแบบกำหนดเอง