1

I'm trying to sort the following List List<char[]> permutations = new List<char[]>();

it contains all the permutations of the number 0,1,2,3,4,5,6,7,8,9 however they are not sorted but I need them sorted. This is what I did to fix my problem :

        permutations = permutations.OrderBy(arr1 => arr1[9]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[8]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[7]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[6]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[5]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[4]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[3]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[2]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[1]).ToList();
        permutations = permutations.OrderBy(arr1 => arr1[0]).ToList();

how can I avoid this or how can this be written in 1 line ?

3 Answers 3

3

First I would note that you are re-sorting the list 9 times.

The proper way to chain orderings is to use ThenBy (note that the order of comparisons is reversed to get the results to order in the same manner that you have now):

    permutations = permutations.OrderBy(arr1 => arr1[0])
                               .ThenBy(arr1 => arr1[1])
                               .ThenBy(arr1 => arr1[2])
                               .ThenBy(arr1 => arr1[3])
                               .ThenBy(arr1 => arr1[4])
                               .ThenBy(arr1 => arr1[5])
                               .ThenBy(arr1 => arr1[6])
                               .ThenBy(arr1 => arr1[7])
                               .ThenBy(arr1 => arr1[8])
                               .ThenBy(arr1 => arr1[9]).ToList();

One simple way to reduce the amount of code is

permutations = permutations.OrderBy(a => new string(a)).ToList();

Or to just order the list in-place.

permutations.Sort((a1, a2) => (new string(a)).CompareTo(new string(a2)));

Granted those generate a lot of strings, but the next best option is to write an IComparer<char[]> that compares two character arrays the way you want it to. One other option (since I know that the list of character arrays came from a different question) would by so store the permutations as strings instead of arrays. Then sorting is a no-brainer:

permutations.Sort();
Sign up to request clarification or add additional context in comments.

6 Comments

Great answer. Just a few notes : OrderBy(a => new string(a)).ToList() && .Sort((a1, a2) => (new string(a1)).CompareTo(new string(a2))); are really slow in performence compared to the .ThenBy method,also the permutations.Sort(); wont work if we are using chars since we don't provide IComparer to it. The first one is almost 4 times faster than the second and the third
1) That's why I said it was a way to reduce code. I'm not surprised it's slower just because of the amount of memory allocated for those strings. Whether or not that's a problem depends on the overall performance of the system.
2) If you stored strings instead of character arrays then you wouldn't need to pass a comparer to Sort - it will sort the strings alphabetically be default. It doesn't work for character arrays since there's not a "default" comparer for char arrays.
nice, the original way could be simplified using a foreach: instead of 10 lines......var order = permutations.OrderBy(e=> e[0]); for (int i = 1; i < 9; i++) order = order.ThenBy(e=> e[i]); var final = order.ToList(); just need to fix the closure :P
i will be captured this way (closure) so it will look like this ` var order = permutations.OrderBy(e => e[0]); for (int i = 1; i < 9; i++) { var i1 = i; order = order.ThenBy(e => e[i1]); } var final = order.ToList();`
|
1

This is pretty old but I was working on this and have a solution that is suggested in comments but not shown. As suggested by George, the dynamic way to handle this is to use a for loop but there is one gotcha as noted here OrderBy / ThenBy in Loop.

This is much faster than converting each char[] to a string as noted in the other comments and answers.

var p = permutations.OrderBy(x => x[0]);
for (int i = 1; i < s.Length; i++)
{
    var index = i; //Must do this to Avoid Gotcha
    p = p.ThenBy(x => x[index]);
}
permutations = p.ToList();

Comments

0

Just use string instead of char[] which is basically IEnumerable<char> In this way you can simply write

permutations.Sort();

if you want to keep it your way you can chain your expressions like:

permutations = permutations.OrderBy(arr1 => arr1[9])
    .ThenBy(arr1 => arr1[8])
    .ThenBy(arr1 => arr1[7])
    .ThenBy(arr1 => arr1[6])
    .ThenBy(arr1 => arr1[5])
    .ThenBy(arr1 => arr1[4])
    .ThenBy(arr1 => arr1[3])
    .ThenBy(arr1 => arr1[2])
    .ThenBy(arr1 => arr1[1])
    .ThenBy(arr1 => arr1[0])
    .ToList();

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.