Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 3 down vote accepted

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();
share|improve this answer
    
This worked perfectly, thank you for the additional information and providing the lookup dictionary. –  opdb Aug 13 '13 at 2:38

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.

share|improve this answer
    
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. –  opdb Aug 13 '13 at 2:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.