tags:

views:

701

answers:

2

I have a list that needs ordering say:

R1-1
R1-11
R2-2
R1-2

this needs to be ordered:

R1-1
R1-2
R1-11
R2-2

Currently I am using the C# Regex.Replace method and adding a 0 before the occurance of single numbers at the end of a string with something like:

Regex.Replace(inString,@"([1-9]$)", @"0$2")

I'm sure there is a nicer way to do this which I just can't figure out. Does anyone have a nice way of sorting letter and number strings with regex?


I have used Greg's method below to complete this and just thought I should add the code I am using for completeness:

public static List<Rack> GetRacks(Guid aisleGUID)
    {
        log.Debug("Getting Racks with aisleId " + aisleGUID);
        List<Rack> result = dataContext.Racks.Where(
                               r => r.aisleGUID == aisleGUID).ToList();
        return result.OrderBy(r => r.rackName, new NaturalStringComparer()).ToList();
    }
+4  A: 

I think what you're after is natural sort order, like Windows Explorer does? If so then I wrote a blog entry a while back showing how you can achieve this in a few lines of C#.

Note: I just checked and using the NaturalStringComparer in the linked entry does return the order you are looking for with the example strings.

Greg Beech
Great answer Greg! I have now used this solution and will add the method i am using in my question for completeness.
bobwah
Ya, great greg! Too bad the LINK is DEAD
Scott
New Link: http://gregbeech.com/blog/natural-sort-order-of-strings-and-files
Scott
@Scott - sorry about that. I simplified the links on my blog and some of the redirects don't seem to be working properly. I've edited the post to have the updated link as well.
Greg Beech
+2  A: 

You can write your own comparator and use regular expressions to compare the number between "R" and "-" first, followed by the number after "-", if the first numbers are equal.

Sketch:

public int Compare(string x, string y)
{
    int releaseX = ...;
    int releaseY = ...;
    int revisionX = ...;
    int revisionY = ...;

    if (releaseX == releaseY)
    {
        return revisionX - revisionY;
    }
    else
    {
        return releaseX - releaseY;
    }
}
chiccodoro
Edit: Hmm.. Greg Beech's solution is nice! -- So take this as a way to solve it if you want to avoid the use of a DllImport.
chiccodoro
Thanks for the response! I have used Greg's solution but nice to have this for others reference.
bobwah