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
而不是OrderBy,因为ThenBy
执行的排序是稳定的,因此保留了具有相等键值的输入元素的排序。
a)在上面的例子中,OrderBy
返回IOrderedEnumerable<>
序列 R ,然后在此序列中调用ThenBy
。当OrderBy
返回 R 时, R 还会存储fruit.Length
用于排序的关键值(OrderBy
值)吗? R 中的元素?
b) R 中存储的键值是什么?
谢谢
答案 0 :(得分:5)
我认为这个问题的答案与你想的不同;
OrderBy
和ThenBy
是所谓的“延期运算符”。你所描述的行为在某种程度上是正确的,但实际上并非......
OrderBy
会返回您建议的类型的引用。但是这个对象不是传统意义上的集合;它是表达式树的一部分。对ThenBy
的后续调用会进一步修改此表达式树。
所述表达式树实际上可能会按照 reverse 顺序进行排序。它甚至可能检测到你每次尝试进行相同的排序,而不是两者都做(你的示例代码中没有做过任何这样的事情,但我只是提出了一点意见)。
特别是,通过执行这些排序,实际上可以快速轻松地完成单个OrderBy
和ThenBy
。请记住关于OrderBy
不确定的内容......
var names = //initialize list of names;
var namesByAlpha = BubbleSort(names=>names);
var namesByAlphaAndLength = BubbleSort(namesByAlpha=>namesByAlpha.Length);
假设BubbleSort
是一种方法,通过下列列表将每个项目与下一个项目进行排序,并在需要时交换位置(仅保留相同的情况),并重复直到整个列表不再需要交换为止。这最终会得到与你发布的LINQ方法相同的结果......但请注意,它按照名称alpha first 进行排序。当它按长度排序后,它会按字母顺序留下等长的名称,从而按OrderBy
长度“先”,然后按字母顺序显示。
OrderBy
和ThenBy
可能不会进行冒泡排序(它在任何可观的大小的集合上都非常低效),但要了解它们的作用,您需要了解它们正在构建枚举集合时执行的表达式树,该表达式树将整个操作列表考虑在内。它不仅仅是做一种,而是做下一次......每次都是单独的操作。
答案 1 :(得分:2)
没有“钥匙”。 OrderBy
返回与原始枚举类型相同的枚举。
答案 2 :(得分:1)
您的键值是从列表中的元素生成的。由于您仍然可以访问已排序列表中的元素,因此仍可以获取键值:
// enumerate the sorted list
foreach (string fruit in query) {
int length = fruit.Length; // grab the key value
// do something with key value
}
这是你的意思吗?也许你正在考虑GroupBy
,它会收集具有相同键值的项目?