2011-05-02 77 views
3
string[] fruits = { "grape", "passionfruit", "banana", "mango", 
          "orange", "raspberry", "apple", "blueberry" }; 

    // Sort the strings first by their length and then 
    //alphabetically by passing the identity selector function. 
    IEnumerable<string> query = 
     fruits.OrderBy(fruit => fruit.Length).ThenBy(fruit => fruit); 

如果我們需要更多的訂貨比它是可能的,以OrderBy單呼,那麼我們就應該繼續調用ThenBy代替排序依據,因爲通過ThenBy進行的排序是穩定的,因此保留了使用相同的鍵值對輸入元素進行排序。排序依據,ThenBy和IOrderedEnumerable <T>

a)在上面的例子中OrderBy返回IOrderedEnumerable<>序列ř並反過來ThenBy被稱爲該序列。當OrderBy返回ř,確實ř還存儲其中使用由OrderByř元素進行排序的關鍵值(fruit.Length值)?

b)哪裏在R是存儲的關鍵值?

謝謝

+0

您是否想過'GroupBy'? – mellamokb 2011-05-02 18:39:32

+0

我正在考慮OrderBy – flockofcode 2011-05-02 19:16:30

回答

5

我認爲這個問題的答案與你想的不同,

OrderByThenBy是所謂的「延期運營商」。什麼你說的那樣的行爲是正確的在一定程度上,但實際上不是......

OrderBy不會返回你的建議的類型的引用。但是這個對象不是傳統意義上的集合;它是表達式樹的一部分。隨後調用ThenBy進一步修改此表達式樹。

上述表達式樹實際上可能會按照您可能假定的順序對反向進行排序。它甚至可能會檢測到你每次都嘗試做同樣的排序,而不是兩者都做(你在示例代碼中沒有做過這樣的事情,但我只是表達了一點)。

特別是,做一個單獨的OrderByThenBy實際上可以通過做出這些排序快速簡單地完成......反過來。牢記什麼是說,大約OrderBy是非確定性...

var names = //initialize list of names; 
var namesByAlpha = BubbleSort(names=>names); 
var namesByAlphaAndLength = BubbleSort(namesByAlpha=>namesByAlpha.Length); 

假設BubbleSort是通過排序去的每一個項目比較下就行,並在需要時更換地點的方法(留下等於案件單獨),並重復,直到整個列表不再需要交換...這最終會得到與您發佈的LINQ方法相同的結果...但請注意,它按名稱alpha 首先執行。當它按照長度進行排序時,它會按照字母順序留下等效長度的名稱,因此會出現OrderBy長度「first」,然後按字母順序排列。

OrderByThenBy可能不這樣做冒泡排序(這是對任何明顯的規模在所有的藏品非常低效的),而是要了解他們在做什麼,你需要了解他們正在建設的時候執行的表達式樹您枚舉集合,並且表達式樹將整個操作列表考慮在內。它不只是做一種,然後做下一個...每一個都是單獨的操作。

+0

我對錶達式樹一無所知,但我確實理解延遲運算符是什麼。例如,OrderBy返回一個實現IOrderedEnumerable對象的對象,只有當枚舉這個對象時,OrderBy查詢纔會被執行。 不管怎樣,我理解你的解釋的方式是,當OrderBy返回的對象R上調用ThenBy時,ThenBy實際上並沒有枚舉對象R,而只是「修改」R的代碼並將此「修改的」R返回給調用者? – flockofcode 2011-05-02 19:14:47

+1

排序;所有延期運營商在任何時候都不會孤立運行。你可以用這種方式來想象它使編寫查詢變得更簡單,但真正發生的是一個表達式樹,它包含*所有的延遲操作符正在建立;只有在通過某些非延期運算符或傳統枚舉序列進行枚舉時纔會完成並執行。所以,'OrderBy'和'ThenBy' *是同一個表達式樹*的一部分。 – 2011-05-02 19:45:12

+0

非常感謝 – flockofcode 2011-05-02 22:49:55

1

你的鍵值從列表中的元素產生。由於您仍然可以訪問排序列表中的元素,因此仍然可以獲得鍵值:

// enumerate the sorted list 
foreach (string fruit in query) { 
    int length = fruit.Length; // grab the key value 
    // do something with key value 
} 

這是您的意思嗎?也許你在考慮GroupBy,它們會一起收集具有相同鍵值的項目?

+0

「這是你的意思嗎?不,請參閱我的回覆安德魯 – flockofcode 2011-05-02 19:16:12

+0

我沒有意識到你想知道它是如何工作*。對不起,我想我太實際了:) – mellamokb 2011-05-02 19:21:10

2

沒有「鑰匙」。 OrderBy返回與原始可枚舉類型相同的枚舉類型。