0

I'm trying to get a list of strings with numbers and characters sorted. The numbers can be units tens, thousands and tens of thousands (greater possibly also).

Here's an example of the strings:

1:     abc
38:    rst
203:   pq
10371: mno
13:    defg
1023:  hi
109:   jkl

For example from list

List<string> list = new List<string>()
{
    "1:     abc",
    "38:    rst",
    "203:   pq",
    "10371: mno",
    "13:    defg",
    "1023:  hi",
    "109:   jkl",
};

My expected result would be

10371: mno
1023:  hi
203:   pq
109:   jkl
38:    rst
13:    defg
1:     abc

I've found this partial solution Sorting mixed numbers and strings

public class MixedNumbersAndStringsComparer : IComparer<string> {
    public int Compare(string x, string y) {
        double xVal, yVal;

        if(double.TryParse(x, out xVal) && double.TryParse(y, out yVal))
            return xVal.CompareTo(yVal);
        else 
            return string.Compare(x, y);
    }
}

    list.Sort(new MixedNumbersAndStringsComparer());

But it sorts it like this instead of as expected above

1:     abc
13:    defg
109:   jkl
1023:  hi
10371: mno
203:   pq
38:    rst

How would you modify the MixedNumbersAndStringsComparer class to get it to sort it as expected? Thanks!

Lod
  • 657
  • 1
  • 9
  • 30
  • 1
    I don't get your "it sorts like this" behavior, I get a lexicographic sort (as expected, none of the items are numbers here): https://rextester.com/RMXZU41109 – Ben Voigt Mar 29 '22 at 20:48
  • Thanks @Ben Voigt for the reply. Yes it is the correct lexicographic order, but you're right I'm looking for the numeric order instead for the first 1 to 5 (or more) numeric characters of the strings. I need the strings as I've tried doing it with SortedList but I get an error of same key already present. rleffler found a good solution. Thanks again! – Lod Mar 29 '22 at 21:03

1 Answers1

1

I am not exactly sure about your question, but I think this is what you are looking for?

List<string> list = new List<string>()
    {
        "1:     abc",
        "38:    rst",
        "203:   pq",
        "10371: mno",
        "13:    defg",
        "1023:  hi",
        "109:   jkl",
    };

var pairedList = new List<Tuple<int, string>>();

foreach (var item in list)
{
    var items = item.Split(':');
    pairedList.Add(new Tuple<int, string>(int.Parse(items[0].Trim()), items[1]));
}

var result = pairedList.OrderByDescending(x => x.Item1).Select(x => x.Item1 + ":" + x.Item2).ToList();

Basically it is just splitting each string in the list by the : and adding the pair to a tuple. From there just order by the int value and reconstruct the list.

rleffler
  • 430
  • 6
  • 15
  • Perfect! Just as needed. Thank you very much! I'll study it in details and be back asa when needed. – Lod Mar 29 '22 at 21:01