1

Say I have the following 2 arrays

string[] keys = new string[]{"Annalee Call","Bishop","Ash"};

MyClass[] vals = new MyClass[]{
    new MyClass(){name = "Ash"},
    new MyClass(){name = "Annalee Call"},
    new MyClass(){name = "Bishop"}
};

What is the best way to sort the MyClass array by name based on the keys array without resorting to for loops?

2 Answers 2

5

One way to do it would be as follows:

var sorted = vals.OrderBy(s => Array.IndexOf(keys, s.name)).ToArray();

Note that this algorithm is asymptotically very slow: it has O(N^2*LogN) complexity. To bring it back to the "normal" O(N*LogN), prepare a lookup dictionary for finding indexes, like this:

var keyDict = keys.Select((v,i)=>new {v,i}).ToDictionary(p=>p.v, p=>p.i);
var sorted = vals.OrderBy(s => keyDict[s.name]).ToArray();
Sign up to request clarification or add additional context in comments.

1 Comment

This worked perfectly, thank you for the additional information and providing the lookup dictionary.
1

I would use this approach to do the sorting. It handles the case if values in vals are missing from the keys list.

var rank =
    keys
        .Select((v, n) => new { Value = v, Rank = n, })
        .ToLookup(vn => vn.Value, vn => vn.Rank);

var query =
    from v in vals
    orderby rank[v.name]
        .DefaultIfEmpty(int.MaxValue)
        .First()
    select v;

Otherwise it is very similar to dasblinkenlight's answer.

1 Comment

You make a good point in checking for the existence of each key. In my current situation a check is not needed, but pretty much every other scenario should implement a key check.

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.