Sắp xếp danh sách theo thứ tự bảng chữ cái


83

Tôi có lớp sau:

class Detail
{
    public Detail()
    {
        _details = new List<string>();
    }
    public IList<string> Details { get { return _details; } }
    private readonly List<string> _details;
}

Hiện tại tôi sắp xếp lớp học một cách ngẫu nhiên bằng cách sử dụng như sau:

void ShuffleGenericList<T>(IList<T> list)
{
    //generate a Random instance
    var rnd = new Random();
    //get the count of items in the list
    var i = list.Count();
    //do we have a reference type or a value type
    T val = default(T);

    //we will loop through the list backwards
    while (i >= 1)
    {
        //decrement our counter
        i--;
        //grab the next random item from the list
        var nextIndex = rnd.Next(i, list.Count());
        val = list[nextIndex];
        //start swapping values
        list[nextIndex] = list[i];
        list[i] = val;
    }
}

Những gì tôi muốn làm là sắp xếp nội dung của các chi tiết theo thứ tự bảng chữ cái.

Vì vậy, ví dụ nếu nội dung trông như thế này:

[0] a
[1] d
[2] b

Tôi muốn có thể chạy phương pháp này và sắp xếp chúng thành:

[0] a
[1] b
[2] d

Có ai biết một cách đơn giản để làm điều này? Lưu ý rằng danh sách thường có ít hơn mười mục nhập trong đó. Tôi có thể làm điều này với LINQ không? Xin lỗi nhưng tôi không rành về LINQ. Tôi vừa nghe một gợi ý rằng tôi có thể sử dụng nó.

Câu trả lời:


154

Bạn có thể sắp xếp một danh sách tại chỗ chỉ bằng cách gọi List<T>.Sort:

list.Sort();

Điều đó sẽ sử dụng thứ tự tự nhiên của các phần tử, điều này tốt trong trường hợp của bạn.

CHỈNH SỬA: Lưu ý rằng trong mã của bạn, bạn cần

_details.Sort();

Sortphương thức chỉ được định nghĩa trong List<T>, không phải IList<T>. Nếu bạn cần sắp xếp nó từ bên ngoài mà bạn không có quyền truy cập vào nó như một List<T>(bạn không nên ép nó vì List<T>phần này là chi tiết triển khai), bạn sẽ cần phải thực hiện thêm một chút công việc.

Tôi không biết về bất kỳ IList<T>loại tại chỗ dựa trên .NET nào, điều này hơi kỳ lạ bây giờ tôi nghĩ về nó. IList<T>cung cấp mọi thứ bạn cần, vì vậy nó có thể được viết dưới dạng một phương thức mở rộng. Có rất nhiều triển khai nhanh chóng xung quanh nếu bạn muốn sử dụng một trong số đó.

Nếu bạn không quan tâm đến một chút kém hiệu quả, bạn luôn có thể sử dụng:

public void Sort<T>(IList<T> list)
{
    List<T> tmp = new List<T>(list);
    tmp.Sort();
    for (int i = 0; i < tmp.Count; i++)
    {
        list[i] = tmp[i];
    }
}

Nói cách khác, sao chép, sắp xếp tại chỗ, sau đó sao chép lại danh sách đã sắp xếp.


Bạn có thể sử dụng LINQ để tạo một danh sách mới chứa các giá trị ban đầu nhưng được sắp xếp:

var sortedList = list.OrderBy(x => x).ToList();

Nó phụ thuộc vào hành vi nào bạn muốn. Lưu ý rằng phương pháp trộn bài của bạn không thực sự lý tưởng:

  • Tạo mới Randomtrong phương thức gặp phải một số vấn đề được hiển thị ở đây
  • Bạn có thể khai báo valbên trong vòng lặp - bạn không sử dụng giá trị mặc định đó
  • Thành ngữ hơn khi sử dụng thuộc Counttính khi bạn biết mình đang làm việc vớiIList<T>
  • Theo suy nghĩ của tôi, một forvòng lặp dễ hiểu hơn là duyệt ngược danh sách bằng một whilevòng lặp

Có những cách triển khai khác của việc xáo trộn với Fisher-Yates trên Stack Overflow - hãy tìm kiếm và bạn sẽ tìm thấy một cách khá nhanh chóng.


Vì vậy, nếu tôi muốn sắp xếp danh sách bạn tạo ở trên thì tôi chỉ cần nói: sortedList.Sort?
Mariko

Tôi đã thử Sắp xếp nhưng không thể làm việc đó. - Danh sách của tôi trông giống như sau: IList <string> nD. Tôi đã thử nD.Sort () nhưng nó nói: Không thể giải quyết biểu tượng 'Sắp xếp'.
Mariko

@Mariko: Sử dụng _details.Sort()thay thế - như _detailsđược khai báo là List<string>thay vì IList<string>. Sortchỉ được khai báo trên List<T>, không phải IList<T>.
Jon Skeet

24

Có hai cách:

Không có LINQ: yourList.Sort();

Với LINQ: yourList.OrderBy(x => x).ToList()

Bạn sẽ tìm thấy thêm thông tin tại: http://www.dotnetperls.com/sort-string-array


@Dminox - Danh sách của tôi trông giống như sau: IList <string> nD. Tôi đã thử nD.Sort () nhưng nó nói: Không thể giải quyết biểu tượng 'Sắp xếp'.
Mariko

1
@Mariko Sort()là thành viên củaList<T> không IList<T> . Bạn có thể cân nhắc chuyển sang phiên bản cũ (trừ khi bạn mong đợi làm việc với các cách IList<T>triển khai khác nhau .)
dlev

23

Cách khác

_details.Sort((s1, s2) => s1.CompareTo(s2)); 

10
Cái này có lợi thế là thích ứng để sắp xếp bất kỳ đối tượng nào theo một trong các thuộc tính của nó .
MGOwen

11

Bạn sẽ có thể sử dụng OrderBytrong LINQ ...

var sortedItems = myList.OrderBy(s => s);

2
Lưu ý: đó là lợi nhuận IEnumerable<T>và không phải là tại chỗ loại
abatishchev

1

Có gì sai với List<T>.Sort()?

http://msdn.microsoft.com/en-us/library/3da4abas.aspx


@goril - Tôi muốn sử dụng cái này nhưng gặp lỗi. Đây là những gì tôi đã thêm vào bình luận khác. Mong bạn giúp đỡ - Danh sách của tôi có dạng: IList <string> nD. Tôi đã thử nD.Sort () nhưng nó nói: Không thể giải quyết biểu tượng 'Sắp xếp'.
Mariko

1
@Mariko: bạn sử dụng giao diện IList <T> không chứa phương thức Sắp xếp. Sort List <T> biến trực tiếp. Nói cách khác, bạn có thể sắp xếp _detailstừ ví dụ của bạn, nhưng khôngDetails
Oleg Dudnyk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.