2010-03-24 34 views
5

tôi có một danh sách mà phần tử là:List <> Comparer riêng

struct element { 
       double priority; 
       int value; 
       } 

Làm thế nào tôi có thể thực hiện Comparer của riêng tôi mà cho phép tôi sắp xếp danh sách bằng cách ưu tiên? Tôi thử với SortredList ... nhưng nó không cho phép các phím douplicated :(

nhờ Big giúp đỡ

+0

Những ngôn ngữ lập trình? –

+0

C#? Java? Lang gì? –

+2

có thể là C#, vì cú pháp <> generic/template, C++ không có bất cứ thứ gì được xây dựng trong tên chính xác 'List', và Java sẽ thích ArrayList hơn. –

Trả lời

3

Nếu bạn không thể dựa vào C# 3 phần mở rộng hoặc Lambdas sau đó bạn có thể có cấu trúc của bạn thực hiện các giao diện IComparable, như vậy:

struct element : IComparable 
{ 
    double priority; 
    int value; 
    public element(int val, double prio) 
    { 
     priority = prio; 
     value = val; 
    } 
    #region IComparable Members 

    public int CompareTo(object obj) 
    { 
     // throws exception if type is wrong 
     element other = (element)obj; 
     return priority.CompareTo(other.priority); 
    } 

    #endregion 
} 

Ngoài ra còn có một typesafe version của giao diện này, nhưng nguyên tắc là như nhau

Sau khi bạn đã giao diện mà thực hiện trên struct hay lớp học của bạn, gọi phương thức Sort trên List<> sẽ "chỉ làm việc"

static void Main(string[] args) 
{ 
    Random r = new Random(); 
    List<element> myList = new List<element>(); 
    for (int i = 0; i < 10; i++) 
     myList.Add(new element(r.Next(), r.NextDouble())); 
    // List is now unsorted 
    myList.Sort(); 
    // List is now sorted by priority 
    Console.ReadLine(); 
} 
+0

Ngay cả trong 2.0, bạn có thể sử dụng phương thức ẩn danh. –

+0

Triển khai tuyệt vời! Cảm ơn ví dụ sử dụng;) Đây là những gì tôi cần! :) – netmajor

+0

Marc: yeah bạn là chính xác. Một lợi ích của phương pháp này mặc dù là nó hoạt động tự động cho tất cả những nơi mà một người nào đó cần phải sắp xếp một bộ sưu tập của 'element's. –

11

Giả sử C# 3 hay muộn:

var sorted = MyList.OrderBy(e => e.priority); 
+0

Giá trị chỉ ra rằng điều này sẽ trả về một 'IEnumerable <>' mới thay vì phân loại 'Danh sách <>' hiện có tại chỗ. – LukeH

+1

Lưu ý rằng điều này sẽ không sắp xếp danh sách, nó sẽ trả về phần tử danh sách theo thứ tự theo phần tử khi được lặp lại. – Blindy

+0

Tôi nghĩ nhiều hơn về phương pháp sắp xếp thao tác thu thập và lưu kết quả. Nhưng Tnx cho điều này cũng! Tôi đánh giá cao sự giúp đỡ của bạn :) – netmajor

1

Nếu bạn muốn sắp xếp danh sách bản thân mà không cần tạo một thể hiện mới, bạn có thể thực hiện IComparer, sau đó gọi List.Sort với một thể hiện của thực hiện của bạn

public class ElementComparer : IComparer<element> 
{ 
    public int Compare(element x, element y) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+1

... với 'ném mới NotImplementedException();' được thay thế bằng 'return x.priority.CompareTo (y.priority);'! :) – gehho

+0

Nếu không có bình luận của gehho Câu trả lời của bạn là một phần .. – netmajor

8

bạn có thể thực hiện một loại tại chỗ bằng cách sử dụng các Sort overload mà phải mất một đại biểu Comparison<T>:

yourList.Sort((x, y) => x.priority.CompareTo(y.priority)); 

Đối với phiên bản cũ của C# bạn sẽ cần phải trao đổi trên các lambda cho cú pháp đại biểu cũ-học:

yourList.Sort(
    delegate(element x, element y) { return x.priority.CompareTo(y.priority); }); 
+0

Tôi đánh giá cao ví dụ về cách sắp xếp hai trường này! – netmajor

+0

Tôi không thể nhận đề xuất lamda để làm việc? Tôi đang sử dụng 3,5, nó nói không thể giải quyết biểu tượng CompareTo – Robs

+1

Lucifer: có lẽ do 'priority' là một thành viên riêng của' element' struct –

2

này phụ thuộc vào nếu bạn muốn sắp xếp danh sách, hoặc lấy các giá trị theo thứ tự được sắp xếp (không thay đổi danh sách).

Để sắp xếp danh sách riêng của mình (giả bạn có một List<element> gọi elements):

elements.Sort((x, y) => x.priority.CompareTo(y.priority)); 
// now elements is sorted 

.NET 2.0 tương đương:

elements.Sort(
    delegate(element x, element y) { 
     return x.priority.CompareTo(y.priority); 
    } 
); 

Để có được các giá trị trong thứ tự sắp xếp:

var orderedElements = elements.OrderBy(x => x.priority); 
// elements remains the same, but orderedElements will retrieve them in order 

Không có LINQ tương đương trong .NET 2.0, nhưng bạn có thể viết của riêng mình:

public static IEnumerable<T> OrderBy<T>(IEnumerable<T> source, Comparison<T> comparison) { 
    List<T> copy = new List<T>(source); 
    copy.Sort(comparison); 

    foreach (T item in copy) 
     yield return item; 
} 

Cách sử dụng:

Comparison<element> compareByPriority = delegate(element x, element y) { 
    return x.priority.CompareTo(y.priority); 
}; 

// unfortunately .NET 2.0 doesn't support extension methods, so this has to be 
// expressed as a regular static method 
IEnumerable<element> orderedElements = OrderBy(elements, compareByPriority); 
+0

Biên soạn tốt mọi câu trả lời: P – netmajor

Các vấn đề liên quan