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开发者_JAVA百科 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
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.
There are no "keys." OrderBy
returns an enumerable of the same type as the original enumerable.
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?
精彩评论