2010-03-24 84 views
5

我有一個列表,其中元素是:列表<>自己的比較器

struct element { 
       double priority; 
       int value; 
       } 

我如何能實現我自己的比較器這讓我排序列表按優先級?我嘗試用SortredList ...但它不允許douplicated鍵:(

非常感謝幫忙

+0

哪種編程語言? – 2010-03-24 16:25:15

+0

C#? Java的?什麼郎? – 2010-03-24 16:26:15

+2

可能是c#,由於<>通用/模板語法,C++沒有任何內置的名字,只是命名爲'List',Java更喜歡ArrayList。 – 2010-03-24 16:26:34

回答

3

如果你不能依靠C#3的擴展或lambda表達式,那麼你可以有你的結構實現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 
} 

也有這個接口的,但原理是一樣的

你有你的結構或類實現該接口後,調用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中,也可以使用匿名方法。 – 2010-03-24 17:12:14

+0

很好的實施!感謝使用示例;)這就是我需要的! :) – netmajor 2010-03-24 17:54:06

+0

馬克:是的,你是對的。這種方法的一個好處是,它可以自動適用於所有需要排序「元素」集合的地方。 – 2010-03-25 07:37:58

11

假設C#3或更高版本:

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

值得指出的是,這將返回一個新的「IEnumerable <>」,而不是在原地對現有的「List <>」進行排序。 – LukeH 2010-03-24 16:34:06

+1

請注意,這不會對列表進行排序,它將在迭代時按元素返回有序列表元素。 – Blindy 2010-03-24 16:34:41

+0

我更想一想操縱集合和保存結果的Sort方法。但Tnx也是這樣!我很感激你的幫助:) – netmajor 2010-03-24 17:59:04

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 2010-03-24 16:41:27

+0

沒有gehho評論您的回答是部分.. – netmajor 2010-03-24 18:19:47

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 2010-03-24 17:56:04

+0

我無法獲得lamda的建議嗎?我使用3.5,它說不能解析符號CompareTo – Robs 2010-03-24 19:45:50

+1

Lucifer:可能是因爲'priority'是'element'的私有成員struct – 2010-03-25 07:40:01

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 2010-03-24 18:00:43