2009-07-20 71 views
10

當我發現沒有直接的方法對IList < T>進行排序或執行二進制搜索時,我非常驚訝。就像有一些靜態方法可以在數組上進行排序和執行二分搜索一樣,我認爲使用IList類似的靜態方法會非常有幫助。爲什麼沒有排序爲IList <T>?!?! (編輯)

目前:

class Array 
{ 
    static Sort<T>(T[] array); 
    static int BinarySearch<T>(T[] array, T item); 
} 

我希望他們能補充:

class List 
{ 
    static Sort<T>(IList<T> list); 
    static int BinarySearch<T>(IList<T> list, T item); 
} 

我看了一眼在.NET Framework 4.0 Beta版SDK和有仍然沒有出現是一個解決方案這個問題。

我知道我可以通過創建一個擴展方法來檢查它是否是列表< T>,然後使用列表< T>實例進行排序/搜索;然而,如果它不是列表< T>的一個實例,那麼我必須執行一個副本(對於非常大的列表來說這很難理解)。我知道我可以做到這一切,但爲什麼?有沒有故意遺漏這個功能的原因?

爲了試圖在.NET 4.0 Framework中獲得這個,我通過微軟的Connect程序創建了一個建議。如果你對我這個問題感到沮喪,請對它投票,也許它會被添加。

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=474201

+0

您能否將這個改爲一個問題,也許是「有什麼原因c#沒有內置排序和二進制搜索IList ?」現在你只是有點發表聲明,並呼籲人們在微軟的網站上爲此投票,因爲它存在被封爲垃圾郵件的風險。 – Kip 2009-07-20 03:27:38

+0

這是一種隱藏在漫無邊際的方式,但有一個問題可以幫助你我明白爲什麼它不存在,如果微軟故意排除它: 「是否有某些原因他們故意省略此功能?」 – dewald 2009-07-20 03:33:18

+0

井堆溢出是一個問題/答案網站。把重點放在你的問題上(特別是在問題的標題中)是一種很好的禮儀。現在聽起來您已經認爲這是一個錯誤,並且您希望其他人告訴Microsoft您同意。 SO的更好的精神在於清楚地表明問題是「是否有充足的理由或者這是一個錯誤?」 – Kip 2009-07-20 03:40:34

回答

17

LINQ有一個OrderBy方法,適用於所有IEnumerable <T>,包括IList <T>。你可以使用OrderBy完成同樣的事情。

// Order a list of addresses: 
IList<string> list = ... 
var orderedList = list.OrderBy(input => input); 
2

你有ArrayList.Adapter,允許使用的ArrayList的排序程序,但它會導致對未裝箱的值類型的泛型列表巨大的性能的影響,再加上兩個虛擬呼叫和調度接口開銷。

對於兩個參考和值類型,接口調度可能是昂貴的,這意味着以ICollection<T>.CopyTo呼叫陣列T[]隨後單獨排序可能是最快的通用選項,包括自定義擴展到直接排序IList<T>對象上。

List<T>具有Sort方法,因爲它可以非常有效類型T[]的底層陣列上操作。根本沒有辦法做到這一點的任意IList<T>

10

我認爲這是一個很不錯的例子,不包括IList<T>的排序方法。首先,它會給那些想要實現IList的人帶來更多的複雜性,其次它會使IList接口難以符合Interface Segregation Principle

我做什麼一般來說,如果我需要在一個IList<T>執行排序是創建一個新的List<T>,並在IList<T>作爲參數傳遞

因此,例如:

 public IList<Address> SortAddresses(IList<Address> addresses) 
     { 
      var sortedAddresses = new List<Address>(addresses); 
      sortedAddresses.Sort(); 
      return sortedAddresses; 
     } 
0

我不是一個C#專家,但很少有List實現支持排序,二進制搜索,甚至索引檢索。列表通常基於linked lists,它們通常不提供通過其索引來檢索項目的方式O(1)。如果你想快速找到一個元素,然後使用一些東西,像tree或其他人所建議的那樣,按照排序順序保存元素。

我的確發現IList包含indexed retrieval method有趣的事實。您可能需要考慮使用SortedList而不是List,因爲它看起來應該支持按索引或鍵在O(1)時間進行的查找。一般來說,如果您需要支持快速查找的內容,請查找一個數據結構,以便按順序保存其元素,而不是顯式地對它們進行排序。如果沒有別的,C#已經有相當多的數據結構。

4

好消息是,你可以寫方法很容易;並感謝C#3.0擴展方法,可以使這項工作在接口上:

public static class ListExt 
{ 
    public static void AddRange<T>(this IList<T> list, IEnumerable<T> items) { 
     foreach(T item in items) list.Add(item); 
    } 
    public static void Sort<T>(this IList<T> list) { 
     Sort<T>(list,Comparer<T>.Default); // ordinal sort by default 
    } 
    public static void Sort<T>(this IList<T> list, IComparer<T> comparer) 
    { // very poor implementation! 
     List<T> concreteList = new List<T>(list); 
     concreteList.Sort(comparer); // cheat! 
     list.Clear(); 
     list.AddRange(concreteList); 
    } 
    public static int BinarySearch<T>(this IList<T> list, T item) { 
     return BinarySearch<T>(list, item, Comparer<T>.Default); 
    } 
    public static int BinarySearch<T>(this IList<T> list, T item, 
     IComparer<T> comparer) 
    {...} // TODO 
} 

現在剩下的工作就是在TODO代碼本身(probaby重新寫Sort ;-p);但在那之後:

IList<T> list = ... 
list.Sort(); 
T huntFor = ... 
int i = list.BinarySearch(huntFor); 

重要的是,IList<T>具有讀/寫索引器,所以它肯定是可以不高於劈做兩排序和二進制搜索。

相關問題