2010-03-24 6 views
5

У меня есть список, где элемент:List <> собственного Comparer

struct element { 
       double priority; 
       int value; 
       } 

Как я могу реализовать свой собственный компаратор, который позволит мне сортировать список по приоритету? Я стараюсь с SortredList ... но не позволяют douplicated ключи :(

Большое спасибо за помощь

+0

Какой язык программирования? – 2010-03-24 16:25:15

+0

C#? Ява? Какой язык? –

+2

, вероятно, C#, из-за синтаксиса <> generic/template, C++ не имеет ничего встроенного с именем точно «List», а Java предпочтет ArrayList. –

ответ

3

Если вы не можете полагаться на C# 3 расширение или Лямбда, то вы можете иметь свою структуру реализовать интерфейс IComparable, например, так:

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 
} 

есть также typesafe version этого интерфейса, но принцип тот же

После того, как вы, что интерфейс, реализованный на вашей структуры или класса, вызвав метод Sort на List<> будет «просто работать»

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

Даже в версии 2.0 вы можете использовать метод анонимного метода. –

+0

Отличная реализация! Спасибо за использование примера;) Это то, что мне нужно! :) – netmajor

+0

Марк: Да, вы правы. Одно из преимуществ этого подхода состоит в том, что он работает автоматически для всех мест, где кому-то нужно сортировать коллекцию 'element'. –

11

Предполагая, что C# 3 или более поздней версии!

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

Стоит отметить, что это вернет новый 'IEnumerable <>' вместо сортировки существующего 'List <>' на месте. – LukeH

+1

Обратите внимание, что это не будет сортировать список, он вернет упорядоченный элемент списка по элементу при повторении. – Blindy

+0

Я больше думаю о методе Сортировки, который управляет сбором и сохраняет результат. Но Tnx для этого тоже! Я ценю вашу помощь :) – netmajor

1

Если вы хотите, чтобы отсортировать список сам без создания нового экземпляра, можно реализовать IComparer, а затем вызвать list.sort с экземпляром вашей реализации

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

... с 'throw new NotImplementedException();' заменено на 'return x.priority.CompareTo (y.priority);'! :) – gehho

+0

Без gehho комментарий Ваш ответ частично .. – netmajor

8

вы можете выполнить то на месте с помощью Sort overload, который принимает Comparison<T> делегата:

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

Для более старых версий C# вы должны поменять лямбду для старой школы делегата синтаксиса:

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

Мне очень понравился этот пример сортировки в двух школах! – netmajor

+0

Я не могу заставить предложение lamda работать? Я использую 3.5, он говорит, что не может решить символ CompareTo – Robs

+1

Люцифер: возможно, из-за 'priority' является частным членом' element' struct –

2

Это зависит от того, если вы хотите сами отсортировать список или получить значения в отсортированном порядке (без изменения списка).

Для сортировки самого списка (предположим, у вас есть List<element> под названием elements):

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

.NET 2.0 эквивалент:

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

Чтобы получить значения в отсортированном порядке:

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

В .NET 2.0 нет эквивалента LINQ, но вы можете написать свой собственный:

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; 
} 

Использование:

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

Хорошая компиляция всех ответов: P – netmajor