tags:

views:

938

answers:

4

I'm trying to come up with a clean way of sorting a set of strings based on a "sorting template". I apologize if my wording is confusing, but I can't think of a better way to describe it (maybe someone can come up with a better way to describe it after reading what I'm trying to do?).

Consider the following list of strings (my "sort template", each item in the list a "command"):

  • [FA, TY, AK, PO, PR, ZZ, QW, BC]

I'd like to use the order of the strings within that list to sort a list of those commands. For example, I'd like the following list:

  • [TY, PR, PR, ZZ, BC, AK]

to be sorted into the following list based on the "sorting template":

  • [TY, AK, PR, PR, ZZ, BC]

What would be a good way to acomplish this? The best idea I have yet is to use an enumeration...

enum Command
{
    FA,
    TY,
    AK,
    PO,
    PR,
    ZZ,
    QW,
    BC
};

...and do an Enum.Parse() on each command in my list I want sorted, converting that list from a list of strings into a list of Commands, which would then be sorted based on the order of the enumeration.

I don't know. The enumeration seems like it would work, but is there a better way I could go about this?

+1  A: 

You could rename your commands like

[1FA, 2TY, 3AK, 4PO, 5PR, 6ZZ, 7QW, 8BC]

and strip out the first character when you were ready to use it. I think that's called a kludge.

I can't help thinking you might get some mileage out of using a SortedList but in effect it propbably will work more or less like your enum

SortedList Commands = new SortedList();
Commands.Add(1,FA);
Commands.Add(2,TY);
//etc
DrG
Hmm - I could just search and replace each command in my source list with a command prefixed with a number, then use a SortedList to go from there... I might give that a try...
unforgiven3
+1  A: 

Use the Command pattern ( I think it's called)

write a sort method that sorts the list, but uses an external method to do the comparison between pairs of objects... Then pass it a delegate to the comparison method... Write the comparison method to take two members of the list, and the sorting template as input parameters... In the method, return a -1, a 0 or a + 1 based on whether the first member of the pair or the second member is found first in the template list.
In your sort method use the return value from the compare method to implement the sort, whatever kind of sort you do...

Charles Bretana
+1  A: 

You could use a Dictionary<string, int> to store and retrieve your sorting template tokens. However, this basically does the same as your enum (only perhaps in a slightly more readable manner), because Enum.Parse here could be confusing.

var ordering = Dictionary<string, int>();
ordering.Add("FA", 0);
ordering.Add("TY", 1); // …

MyList.Sort((a, b) => ordering[a].CompareTo(ordering[b]));

This uses an appropriate overload of the List<T>.Sort method to compare two elements based on their value in the template dictionary.

Konrad Rudolph
This is perfect, it works great! Thank you very much!
unforgiven3
Yes, this is what I was thinking, but I couldn't quite articulate it (or do it :D)
DrG
+3  A: 

Here is a very simple way to do it!

List<string> template = new List<string>{ "ZD", "AB", "GR"};

List<string> myList = new List<string>{"AB", "GR", "ZD", "AB", "AB"};
myList.Sort((a, b) => template.IndexOf(a).CompareTo(template.IndexOf(b)));
John Sonmez
I really like the use of IndexOf(), I'm using that now. Thanks!
unforgiven3