OrderBy、ThenBy 和 IOrderedEnumerable

发布于 2024-11-04 14:48:51 字数 876 浏览 0 评论 0原文

    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< 执行的/code> 是稳定的,因此保留具有相同键值的输入元素的顺序。

a) 在上面的示例中,OrderBy 返回 IOrderedEnumerable<> 序列 R,并依次调用 ThenBy顺序。当 OrderBy 返回 R 时,R 是否还存储由OrderByR 中的元素进行排序?

b) 键值存储在R中的什么位置?

谢谢

    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);

If we need more ordering than it is possible with a single call to OrderBy, then we should subsequently call ThenBy instead of OrderBy, since the sort performed by ThenBy is stable and thus preserves the ordering of input elements with equal key values.

a) In the above example OrderBy returns IOrderedEnumerable<> sequence R and in turn ThenBy is called on this sequence. When OrderBy returns R, does R also store the key values (fruit.Length values ) which were used by OrderBy to sort the elements in R?

b) Where in R are key values stored?

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栀子花开つ 2024-11-11 14:49:15

您的键值是根据列表中的元素生成的。由于您仍然可以访问排序列表中的元素,因此您仍然可以获得键值:

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

是这个意思吗?也许您正在考虑 GroupBy,它将具有相同键值的项目收集在一起?

Your key values are generated from the elements in the list. Since you still have access to the elements in the sorted list, you can still get the key value:

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

Is that what you mean?? Maybe you are thinking about GroupBy, which would collect items with the same key value together?

永言不败 2024-11-11 14:49:14

没有“钥匙”。 OrderBy 返回与原始可枚举类型相同的可枚举。

There are no "keys." OrderBy returns an enumerable of the same type as the original enumerable.

给不了的爱 2024-11-11 14:49:13

我认为这个问题的答案与你想象的不同;

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 长度“先”显示,然后按字母顺序显示。

OrderByThenBy 可能不会执行冒泡排序(对于任何可观大小的集合来说,它的效率都非常低),但是要了解它们的作用,您需要了解他们正在构建一个表达式树,当您枚举集合时执行该表达式树,并且该表达式树正在考虑操作的总列表。它不仅仅是进行一种排序,然后进行下一种排序……每一项都作为单独的操作。

I think the answer to this question lies somewhere different than you are thinking;

OrderBy and ThenBy are what are known as "deferred operators". What you described as the behavior is correct on some level, but actually not...

OrderBy does return a reference of the type you suggest. But that object is not a collection in the traditional sense; It is a part of an expression tree. Subsequent calls to ThenBy further modify this expression tree.

Said expression tree might actually do the sorting in the reverse order to what you might assume. It might even detect that you tried to do the same sorting each time, and not do them both (you haven't done any such thing in your example code, but I'm just making a point).

In particular, doing a single OrderBy and ThenBy could actually be quickly and easily done by doing those sorts... in reverse. Keeping in mind what is said about OrderBy being non-determinate...

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

Assuming BubbleSort is a method which sorts by going down the list comparing each item to the next, and exchanging places when required (leaving equal cases alone), and repeats until the whole list no longer needs exchanging... this would end up with the same results as the LINQ methods you post... but note that it does the sort by names alpha first. When it sorts by length later, it would leave names of equivalent length in their alphabetical order, thereby appearing to OrderBy the length "first", then alphabetically.

OrderBy and ThenBy probably don't do a Bubble Sort (it's very inefficient on collections of any appreciable size at all), but to understand what they do, you need to understand they are building an expression tree that is executed when you enumerate the collection, and that expression tree is taking the total list of operations into account. It is not merely doing one sort, then doing the next... each as separate operations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文