0

Based on my previous question, I've trying now to have them in the following order using the same approach, OrderByDescending and ThenBy

Original (can be in any random order):

1:1
0:0
0:1
2:1
1:0
2:0

Output

2:0 
1:0 
0:0 
2:1 
1:1 
0:1

as you can see, a is descending, and b being ascending. But I'm still not getting the right sort. Any ideas why? Thanks

6
  • 1
    I would first Accept the most helpful answer in your first question then ask nicely in a comment for the author of that answer to have a look in this new question. If this one is closely related to the first, you can edit your first question with this and Delete this one. Commented Apr 3, 2011 at 14:51
  • 1
    At least quote the relevant part(s) from your previous question and add a link to it. We're not doing sequels here. Commented Apr 3, 2011 at 14:51
  • Sorry about that, I'm still new in here :) Link: stackoverflow.com/questions/5527230/… Commented Apr 3, 2011 at 14:54
  • The solution(s) in the previous question seem easily adaptable to your new sort order - what have you tried? Commented Apr 3, 2011 at 15:02
  • 1
    Please use List<string> not ArrayList Commented Apr 3, 2011 at 15:04

2 Answers 2

3

Think to what you would do manually:

  1. First you must sort the values by the 2nd part in ascending order
  2. Then you must sort values having the same 2nd part, using the 1st part in descending order

Translated in LINQ it's pretty the same:

var sorted = arrayList
.Cast<string>()
.Select(x => x.Split(':'))
.OrderBy(x => x[1])
.ThenByDescending(x => x[0])
.Select(x => x[0] + ":" + x[1]);

To clarify a bit more, ThenBy/ThenByDescending methods are used to sort elements that are equal in the previous OrderBy/OrderByDescending, hence the code :)

Sign up to request clarification or add additional context in comments.

9 Comments

great answer but one thing I'd change is the last select to an Aggregate instead.
@philip : Aggregate() is similar to Sum(), it transforms a list to a single element. Here we want a list, we just need to change each element into something else (i.e. projection) and Select() is the right method to use in case of projection :)
I use it to concatenate strings all the time i.e. - .Aggregate((lhs,rhs) => lhs + ":" + rhs)
@philip: Oh, you meant inside the Select, i.e. Select(x => x.Aggregate((l, h) => l + ":" + h)); yes, you can also use that even if I prefer string.Join for strings. Anyway, in this case there are just 2 little strings then a simple concatenation is more readable IMO.
@philip: actually also string.Join() doesn't add the separator after the last field. For string joining Aggregate() and string.Join() give the same results, peraphs string.Join is better because it uses less memory using a StringBuilder under the hood and IMO is more readable :)
|
0
arrayList.ToList().Select(i => { var split = i.Split(":".ToArray(),2));
                                return new { a = Int32.Parse(split[0]),
                                             b = Int32.Parse(split[1}) }; 
                               })
.OrderByDescending(i => i.a)
.ThenBy(i => i.b)

From your question it is not clear whether you want the order-by's reversed (just swap them). Work from there, perhaps rejoining

.Select(i => String.Format("{0}:{1}", i.a, i.b));

Good luck

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.