Các cách sắp xếp 1 danh sách đối tượng trong C#

Các cách sắp xếp 1 danh sách đối tượng trong C#

Trong lập trình hướng đối tượng, chắc hẳn các bạn cũng thường thao tác với tập hợp một mảng, một danh sách,.. các đối tượng. Vậy chắc hẳn các bạn đã có đôi lần nghĩ về cách sắp xếp chúng, hôm nay mình sẽ liệt kê 1 vài cách sắp xếp mà mình biết :

1. Sắp xếp với LinQ

2. Sắp xếp với IComparable

3. Sắp xếp với IComparer

Cùng tìm hiểu chi tiết qua từng ví dụ với mình nhé 😉😉😉

Chuẩn bị: Kiến thức cơ bản về C#, OOP và 1 Project như sau:

  • Project Console với cấu trúc như sau:

  • Class Person

using System;
using System.Collections.Generic;
using System.Text;

namespace DemoObjectSort
{
    class Person
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public Person(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }

        public void GetInfo()
        {
            Console.WriteLine("Name: {0}, Age: {1}", Name, Age);
        }
    }
}
  • Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoObjectSort
{
    class Program
    {
        static List<Person> PersonList = new List<Person>();
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.Unicode; //Hiển thị unicode của tên các Idol =))
            PersonList.Add(new Person("Lão Hạc", 80));
            PersonList.Add(new Person("Khá Bảnh", 20));
            PersonList.Add(new Person("Huấn Rouse", 31));
        }
    }
}

Sắp xếp với LinQ

LinQ là 1 công cụ cực kỳ mạnh gắn liền với .Net Framework, nó có thể tìm kiếm, sắp xếp với nhiều kiểu dữ liệu khác nhau, chi tiết hơn mọi người có thể tham khảo bài viết về LinQ của mình, ở đây mình sẽ đề cập đến việc sử dụng để sắp xếp 1 danh sách đối tượng trong C#.

Ví dụ cụ thể

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

namespace DemoObjectSort
{
    class Program
    {
        static List<Person> PersonList = new List<Person>();
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.Unicode; //Hiển thị unicode của tên các Idol =))
            PersonList.Add(new Person("Lão Hạc", 80));
            PersonList.Add(new Person("Khá Bảnh", 20));
            PersonList.Add(new Person("Huấn Rouse", 31));

            var PersonListSort = PersonList.OrderBy(P => P.Age);
            //var PersonListSort = PersonList.OrderByDescending(P => P.Name); //Sắp xếp theo tên từ Z - A
            foreach (Person person in PersonListSort)
            {
                person.GetInfo();
            }
        }
    }
}

  • Kết quả là ta đã sắp xếp thứ tự theo tiêu chí theo Age của Person

Sắp xếp với IComparable

  • Ở đây ta sẽ sắp xếp thông qua phương thức Sort của danh sách các đối tượng được lưu trữ bằng List<T>, nếu T là danh sách các kiểu dữ liệu cơ bản như int, float, string của C# thì bạn có thể sắp xếp được với Sort() nhưng với 1 kiểu dữ liệu do người dùng tự định nghĩa thì bạn phải chỉ rõ tiêu chí mà bạn muốn sắp xếp, và khi sử dụng hàm Sort này đối với List dữ liệu đó thì hàm Sort sẽ thực thi sắp xếp danh sách dựa trên tiêu trí này.
  • Giá trị trả về nhỏ hơn 0 nghĩa là đối tượng hiện tại sẽ nhỏ hơn (hay đứng trước) đối tượng other. Giá trị trả về là 0 thì hai đối tượng bằng nhau, còn nếu giá trị trả về lớn hơn 0 thì đối tượng hiện tại lớn hơn (hay đứng sau) đối tượng other.
  • Để khai báo tiêu chí sắp xếp vời hàm Sort chúng ta sẽ cần phải Implement Interface IComparable trên class được định nghĩa để chỉ ra thuộc tính mà ta sử dụng cho việc sắp xếp thông qua phương thức CompareTo của interface này.

Ví dụ cụ thể

  • Class Person
using System;
using System.Collections.Generic;
using System.Text;

namespace DemoObjectSort
{
    class Person : IComparable<Person>
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public Person(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }

        public void GetInfo()
        {
            Console.WriteLine("Name: {0}, Age: {1}", Name, Age);
        }

        public int CompareTo(Person obj) // OverRight phương thức CompareTo của Interface IComparable
        {
            return this.Age.CompareTo(obj.Age); //Phương thức CompareTo này có sẵn với các kiểu cơ bản như Integer, String.
        }
    }
}

  • Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoObjectSort
{
    class Program
    {
        static List<Person> PersonList = new List<Person>();
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.Unicode; //Hiển thị unicode của tên các Idol =))
            PersonList.Add(new Person("Lão Hạc", 80));
            PersonList.Add(new Person("Khá Bảnh", 20));
            PersonList.Add(new Person("Huấn Rouse", 31));

            PersonList.Sort();
             foreach (Person person in PersonList)
             {
                 person.GetInfo();
             }
        }
    }
}
  • Kết quả:

Các Idol đã được sắp xếp theo tứ tự độ tuổi tăng dần, hãy thử thay đổi phần return của phương thức CompareTo như sau để xem thứ tự các Idol có được xếp theo độ tuổi giảm dần không nhé 😜

return obj.Age.CompareTo(this.Age);

Sắp xếp với IComparer

  • Tương tự như với sắp xếp List<T> với hàm Sort bên trên, mở rộng hơn so với dùng IComparable là ở đây bạn sẽ sắp xếp với hàm Sort trên khía cạnh nhiều tiêu trí hơn
  • Để khai báo các tiêu chí sắp xếp chúng ta sẽ tạo ra 1 class thực thi Interface IComparer để triển khai thuộc tính mà ta sử dụng cho việc sắp xếp thông qua phương thức Compare của interface này, với nhiều tiêu chí khác nhau ta sẽ tạo ra nhiều class thực thi Interface IComparer khác nhau.
  • Khi sử dụng hàm Sort ta sẽ truyền 1 tham số là 1 Object được tạo ra từ class thực thi Interface IComparer bên trên.

Ví dụ cụ thể

  • Từ Project ở phần chuẩn bị tạo 2 class SortPersonByName.cs và SortPersonByAge.cs:
  • Class SortOrderByName.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;

namespace DemoObjectSort
{
    class SortPersonByName : IComparer<Person>
    {
        public int Compare([AllowNull] Person x, [AllowNull] Person y)
        {
            return x.Name.CompareTo(y.Name);
            //return y.Name.CompareTo(x.Name); ////Thử đổi phần return như này xem kết quả thay đổi ra sao nhé
        }
    }
}

  • Class SortOrderByAge.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;

namespace DemoObjectSort
{
    class SortPersonByAge : IComparer<Person>
    {
        public int Compare([AllowNull] Person x, [AllowNull] Person y)
        {
            return x.Age.CompareTo(y.Age);
            //return y.Age.CompareTo(x.Age); //Thử đổi phần return như này xem kết quả thay đổi ra sao nhé
        }
    }
}
  • Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoObjectSort
{
    class Program
    {
        static List<Person> PersonList = new List<Person>();
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.Unicode; //Hiển thị unicode của tên các Idol =))
            PersonList.Add(new Person("Lão Hạc", 80));
            PersonList.Add(new Person("Khá Bảnh", 20));
            PersonList.Add(new Person("Huấn Rouse", 31));

            PersonList.Sort(new SortPersonByName());
             foreach (Person person in PersonList)
             {
                 person.GetInfo();
             }
        }
    }
}

  • Kết quả là ta đã sắp xếp thứ tự theo tiêu chí theo Name của Person

  • Trong Sort() ở Program.cs, ta sửa thành:

PersonList.Sort(new SortPersonByAge());
  • Kết quả là ta đã sắp xếp thứ tự theo tiêu chí theo Age của Person

Tổng kết

  • Trên đây mình đã trình bày về một số cách sắp xếp thông dụng 1 danh sách đối tượng trong C#, tùy từng tình huống:

    • Sắp xếp trực tiếp ngắn gọn với LinQ
    • Sắp xếp 1 duy nhất 1 tiêu trí có thể tái sử dụng với IComparable
    • Sắp xếp có thể theo nhiều tiêu trí và có thể tái sử dụng với IComparer

Cảm ơn vì đã theo dõi ❤️


All Rights Reserved