You can get this down to two lines (one for array definition, one for ordering):
var PackageOrder = new[] { "KK %", "AB", "AB art", "DD %", "FV", "ER", "PP", "WW"};
//...
var list = mail.Package.OrderBy(p => Array.IndexOf(PackageOrder, p.Name)).ToList();
But we can do even better.
The code so far either requires several O(n) lookups into the reference array, or switching to a Dictionary<string,int>
, which is O(1) for each lookup for a value of 1
that might be disproportionate to the task. Each package item may need several of these lookups over the course of a sort operation, which means this might be less efficient than you want.
We can get around that like this:
private static string[] Names = new[] { "KK", "AB", "BC", "DD", "FV", "ER", "PP", "WW" };
//...
var list = mail.Package.
Select(p => new {Package = p, Index = Array.IndexOf(Names, p.Name)}).
OrderBy(p => p.Index).
Select(p => p.Package).ToList();
This guarantees only one lookup per package over the course of the sort. The idea is to first create a projection of the original data that also includes an index, then sort by the index, and finally project back to just the original data. Now the only question is whether to use an array or dictionary, which mainly depends on the size of the reference array (for this size data stick with the array, for more than about 15 items, switch to the dictionary; but it varies depending on the GetHashCode()
performance of your type).
Of course, there's also YAGNI to consider. For large sets this will typically be much better, but for small data it might not be worth it, or if the data happens to be sorted in a certain lucky ways it can make things slower. It can also make things slower if your are more constrained by memory pressure than cpu time (common on web servers). But in the general sense, it's a step in the right direction.
Finally, I question the need for an actual List<T>
here. Just change the declaration to var
and remove the .ToList()
at the end. Wait to call ToList()
or ToArray()
until you absolutely need it, and work with the simple IEnumerable<T>
until then. This can often greatly improve performance.
In this case (and for reference, I added this paragraph later on), it seems like you only have eight items total, meaning the extra code isn't really saving you anything. With that in mind, I'd just stick with the two-line solution at the top of this answer (when performance doesn't matter, go for less or simpler code).