tags:

views:

171

answers:

5

I'm in a little bit of a bind. I'm working with a legacy system that contains a bunch of delimited strings which I need to parse. Unfortunately, the strings need to be ordered based on the first part of the string. The array looks something like

array[0] = "10|JohnSmith|82";
array[1] = "1|MaryJane|62";
array[2] = "3|TomJones|77";

So I'd like the array to order to look like

array[0] = "1|MaryJane|62";
array[1] = "3|TomJones|77";
array[2] = "10|JohnSmith|82";

I thought about doing a 2 dimensional array to grab the first part and leave the string in the second part, but can I mix types in a two dimensional array like that?

I'm not sure how to handle this situation, can anyone help? Thanks!

+13  A: 

Call Array.Sort, but passing in a custom implementation of IComparer<string>:

// Give it a proper name really :)
public class IndexComparer : IComparer<string>
{
    public int Compare(string first, string second)
    {
        // I'll leave you to decide what to do if the format is wrong
        int firstIndex = GetIndex(first);
        int secondIndex = GetIndex(second);
        return firstIndex.CompareTo(secondIndex);
    }

    private static int GetIndex(string text)
    {
        int pipeIndex = text.IndexOf('|');
        return int.Parse(text.Substring(0, pipeIndex));
    }
}

Alternatively, convert from a string array into an array of custom types by splitting the string up appropriately. This will make life easier if you're going to do further work on the array, but if you only need to sort the values, then you might as well use the code above.

You did say that you need to parse the strings - so is there any particular reason why you'd want to parse them before sorting them?

Jon Skeet
Thanks, this works perfectly! (although I had to change the private method to below for some reason) private static int GetIndex(string text)
Wil
Sorry to not be clear, parsing is definitely post sort. Thanks again!
Wil
+1  A: 

Use an ArrayList (http://msdn.microsoft.com/en-us/library/system.collections.arraylist_methods(VS.80).aspx) so you can sort it.

Ryan Miller
Why would that help? Array already has sorting methods available on it.
Jon Skeet
+6  A: 
        new[] {
            "10|JohnSmith|82",
            "1|MaryJane|62",
            "3|TomJones|77",
        }.OrderBy(x => int.Parse(x.Split('|')[0]));
Jay Bazuzi
Just tried this out and it seemed to work well, I choose the other answer though to give me more flexibility, thanks!
Wil
One thing to note (not a criticism, just a difference) between OrderBy and Sort is that Sort does it in-place - it changes the contents of the array. OrderBy returns a new sequence which is ordered.
Jon Skeet
A: 

for lolz

Array.Sort(array, ((x,y) => (int.Parse(x.Split('|')[0]) < int.Parse(y.Split('|')[0])) ? -1 : (int.Parse(x.Split('|')[0]) > int.Parse(y.Split('|')[0])) ? 1 : 0));
Paul Creasey
+1  A: 

If the array is large, you will want to extract the initial integers all in one pass, so you are not parsing strings at every comparison. IMO, you really want to encapsulate the information encoded in the strings into a class first. Then sort the array of those objects.

Something like:

class Person {
  int Index { get; }
  string Name { get; }
  int Age { get; }  // just guessing the semantic meaning
}

So then:

  1. Map your encoded string into an ArrayList of Person objects.
  2. Then use ArrayList.Sort(IComparer) where your comparer only looks at the Index.

This will likely perform better than using parse in every comparison.

Dagititis
Sorry, I missed that Jon Skeet also suggested to parse first, then sort. I support his answer.
Dagititis