2011-05-02 71 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返回与原始可枚举类型相同的枚举类型。