0

Am I correct in understanding that a orderbydescending doesnt actually rearrange the order of a list? and if so what would be the best method around this?

newList= myOldList.OrderByDescending(x => x.DateTime)
                            .ThenBy(x => x.Status)
                            .Where(x => x.Status != StatusEnum.Complete).ToList();

This does not seem to be actually rearranging them, what would be the most effective way?

Thank you.

TheAkhemist
  • 219
  • 1
  • 14
  • Rearranging them in what way? – Harry Mar 01 '16 at 12:11
  • try order by after where clause – Kaushik Mar 01 '16 at 12:11
  • Can you provide a small sample that demonstrates the issue? If you want to order the old list too you have to reassign `newList` to `myOldList`. – Tim Schmelter Mar 01 '16 at 12:15
  • You should also note that sorting on an enum uses the underlying numerical values, not the labels. If StatusEnum.Complete has an underlying value of 1 and StatusEnum.InProgress has an underlying value of 0, then InProgress will come before Complete in the sorted output. – Grax32 Mar 01 '16 at 12:49

2 Answers2

1

You need to order them after you filtered the results, Where returns an IEnumerable, not an IOrderedEnumerable.

But you are correct to say that using the order methods on a collection doesn't order the collection itself. It does return an ordered version of the collection.

Edit: As Tim Schmelter says in the comments, Where doesn't change the order, but if you're going to sort your data, you'd better return the appropriate interface.

Alexander Derck
  • 13,818
  • 5
  • 54
  • 76
  • 2
    But `Where` doesn't change the order. Using `Where` first is better anyway because there is less to order. – Tim Schmelter Mar 01 '16 at 12:12
  • Not necessary; If you query a database; the the result is going to be IQueryable and not IEnumerable. – Alex Suleap Mar 01 '16 at 12:16
  • 1
    @AlexSuleap: But it's about a List which is Linq-To-Objects. – Tim Schmelter Mar 01 '16 at 12:17
  • @AlexSuleap List would be a terrible name for an `IQueryable` ;-) – Alexander Derck Mar 01 '16 at 12:17
  • Sorting first and then extracting the result will be slower than extracting the results and than sorting. Why: To sort the list linq uses quick sort which is O(n log n) in average. To extract the results is O(n). Sorting a smaller list is faster. – Alex Suleap Mar 01 '16 at 12:23
  • It's not that complicated, complexity doesn't matter but the order of operations. As i've said, if you have to sort all and then your filter throw away most of it, you've sorted a lot for no reason. If you first filter there's less to sort. When i started with LINQ this was also confusing me. E.Lippert gave me a nice example: http://stackoverflow.com/questions/10110013/order-of-linq-extension-methods-does-not-affect-performance – Tim Schmelter Mar 01 '16 at 12:26
1

You need to change the order you are calling your Linq query chain it should be

newList= myOldList.Where(x => x.Status != StatusEnum.Complete).OrderByDescending(x => x.DateTime)
                        .ThenBy(x => x.Status)
                        .ToList();
James Dev
  • 2,979
  • 1
  • 11
  • 16
  • Why is it needed? The `Where` should preserve order http://stackoverflow.com/questions/7259560/does-enumerable-where-in-linq-to-objects-preserve-order While it is for sure good idea to filter first, is it needed? – Antonín Lejsek Mar 01 '16 at 14:02