2

I have a List looks like:

List<string> newList = new List<string>() { "10S", "XS", "80", "5S", "160", "40S", "80S", "STD", "40", "XXS" };

And I want to sort it to

  • { "40", "80", "160", "5S", "10S", "40S", "80S", "STD", "XS", "XXS" };

How should I do it? Hope anyone can help me on this issue, thanks a lot!

SIAX
  • 37
  • 1
  • Duplicate of http://stackoverflow.com/questions/188141/c-sharp-list-orderby-alphabetical-order – Benjamin Gruenbaum May 21 '13 at 02:41
  • You will have to overwrite sorting function (write your own). I dont think default sort will sort the way you want. – Guanxi May 21 '13 at 02:42
  • You need to define a comparison function that returns a value indicating the order you want them in. None of the pre-defined comparisons will work for this. – Corey May 21 '13 at 02:42
  • 3
    Is there a specific **sorting rule** that I'm not able to see? So you want a asc number sort, then asc letter + number and then a asc letter sort? – Chief Wiggum May 21 '13 at 02:43
  • take a look here => http://stackoverflow.com/questions/6396378/c-sharp-linq-orderby-numbers-that-are-string-and-you-cannot-convert-them-to-int as the guys mentioned you'll need to create your own comparison func that link should give you the idea. – origin1tech May 21 '13 at 02:46
  • JamesBlond yes that exactly the rule I want – SIAX May 21 '13 at 02:46

2 Answers2

2
List<string> list = new List<string>() { "10S", "XS", "80", "5S", "160", "40S", "80S", "STD", "40", "XXS" };

// filter out numbers:
int temp;
var newList = (from item in list where int.TryParse(item, out temp) select item).ToList();

// sort by number and get back string:
newList = newList.Select(x => int.Parse(x)).OrderBy(x => x).Select(x => x.ToString()).ToList();

// sort the rest by string:
var second = list.Except(newList).OrderBy(x => x).ToList();

// Merge the two back together
newList.AddRange(second);

newList will now be : { "40", "80", "160", "5S", "10S", "40S", "80S", "STD", "XS", "XXS" };

basarat
  • 261,912
  • 58
  • 460
  • 511
  • 1
    Nice solution there. And you could even sort right away after filtering out the numbers like: var newList = (from item in list where int.TryParse(item, out temp) select item).OrderBy(x=>int.Parse(x)).ToList(); But probably you are looking at pedagogical value here more than terseness. – Edper May 21 '13 at 04:09
0

I write some code and it works. I just use the Linq to do what you want

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

namespace SortTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //your objects
            List<string> newList = new List<string>() { "10S", "XS", "80", "5S", "160", "40S", "80S", "STD", "40", "XXS" };

            //filter the stuff you want first, and then sort them from small to big
            var sQuery = newList.Where(p => p.EndsWith("s", StringComparison.CurrentCultureIgnoreCase)).OrderBy(p => p);
            var numQuery = newList.Where(p => Regex.IsMatch(p, "^[0-9]+$", RegexOptions.Singleline)).OrderBy(p => p);
            var otherQuery = newList.AsQueryable().Where(p => !sQuery.Contains(p) && !numQuery.Contains(p));

            //get the result, add the sorts
            List<string> resultList = new List<string>();
            resultList.AddRange(numQuery);
            resultList.AddRange(sQuery);
            resultList.AddRange(otherQuery);

            //print them out
            Console.Write(string.Join(",", resultList.ToArray()));

            Console.WriteLine();
            Console.ReadKey();
        }
    }
}
Tim Li
  • 215
  • 1
  • 2
  • 8