Reputation: 221
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?
Upvotes: 1
Views: 3836
Reputation: 117064
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.
Upvotes: 1
Reputation: 726589
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();
Upvotes: 5