1

I have the following list of string

var strTest = new List<string> { "B2", "B1", "B10", "B3" };

I want to sort them as follows "B1, B2, B3, B10".

If I use LINQ OrderBy it sorts this way "B1, B10, B2, B3"

Please help. Here's my code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SortingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var strTest = new List<string> { "B2", "B1", "B10", "B3" };
            var sort = strTest.OrderBy(x => x);
            var sortedStr = string.Join(",", sort);
            Console.WriteLine(sortedStr);
            Console.ReadLine();
        }
Jobert Enamno
  • 4,403
  • 8
  • 41
  • 63
  • Also look at the answers here: http://stackoverflow.com/questions/248603/natural-sort-order-in-c-sharp and here: http://stackoverflow.com/questions/1323550/linq-and-a-natural-sort-order – Matthew Watson Jun 24 '13 at 07:50

5 Answers5

5

try this:

    var strTest = new List<string> { "B1", "B2", "B3", "B10" };
    strTest.Sort((s1, s2) => 
    {
        string pattern = "([A-Za-z])([0-9]+)";
        string h1 = Regex.Match(s1, pattern).Groups[1].Value;
        string h2 = Regex.Match(s2, pattern).Groups[1].Value;
        if (h1 != h2)
            return h1.CompareTo(h2);
        string t1 = Regex.Match(s1, pattern).Groups[2].Value;
        string t2 = Regex.Match(s2, pattern).Groups[2].Value;
        return int.Parse(t1).CompareTo(int.Parse(t2));
    });
ojlovecd
  • 4,812
  • 1
  • 20
  • 22
  • 2
    Great answer - in case anyone needs to apply this to strings that may or may not have numerics and/or spaces, just need to modify the pattern to : `string pattern = "([A-Za-z\\s]*)([0-9]*)";` – Gumzle May 16 '14 at 12:38
3
 var sort = strTest.OrderBy(x => int.Parse(x.Replace("B",string.Empty)));

output: B1,B2,B3,B10

Voice
  • 194
  • 6
1

Replace B with empty string and convert the remaining string into number.

var sort = strTest.OrderBy(x => Convert.ToInt32(x.Replace("B", "")));
John Woo
  • 258,903
  • 69
  • 498
  • 492
1

you may try this

   var strTest = new List<string> { "B2", "B1", "B10", "B3" };

   var res = strTest.OrderBy(x=> int.Parse(x.Split('B')[1]));

or,

  var strTest = new List<string> { "B2", "B1", "B10", "B3" };
  var res = strTest.OrderBy(x=> int.Parse(x.Remove(0,1)));
A.T.
  • 24,694
  • 8
  • 47
  • 65
0

something like

public static string PadNumbers(string input)
{
    return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(10, '0'));
}

then

var result = partNumbers.OrderBy(x => PadNumbers(x));
Saif
  • 394
  • 3
  • 13