How to sort out numeric strings as numerics?

前端 未结 6 2008
面向向阳花
面向向阳花 2020-12-30 09:04

If you have strings like:

\"file_0\"
\"file_1\"
\"file_2\"
\"file_3\"
\"file_4\"
\"file_5\"
\"file_6\"
\"file_11\"

how can you sort them so

6条回答
  •  南方客
    南方客 (楼主)
    2020-12-30 09:29

    To handle sorting of intermixed strings and numbers for any kind of format, you can use a class like this to split the strings into string and number components and compare them:

    public class StringNum : IComparable {
    
       private List _strings;
       private List _numbers;
    
       public StringNum(string value) {
          _strings = new List();
          _numbers = new List();
          int pos = 0;
          bool number = false;
          while (pos < value.Length) {
             int len = 0;
             while (pos + len < value.Length && Char.IsDigit(value[pos+len]) == number) {
                len++;
             }
             if (number) {
                _numbers.Add(int.Parse(value.Substring(pos, len)));
             } else {
                _strings.Add(value.Substring(pos, len));
             }
             pos += len;
             number = !number;
          }
       }
    
       public int CompareTo(StringNum other) {
          int index = 0;
          while (index < _strings.Count && index < other._strings.Count) {
             int result = _strings[index].CompareTo(other._strings[index]);
             if (result != 0) return result;
             if (index < _numbers.Count && index < other._numbers.Count) {
                result = _numbers[index].CompareTo(other._numbers[index]);
                if (result != 0) return result;
             } else {
                return index == _numbers.Count && index == other._numbers.Count ? 0 : index == _numbers.Count ? -1 : 1;
             }
             index++;
          }
          return index == _strings.Count && index == other._strings.Count ? 0 : index == _strings.Count ? -1 : 1;
       }
    
    }
    

    Example:

    List items = new List {
      "item_66b",
      "999",
      "item_5",
      "14",
      "file_14",
      "26",
      "file_2",
      "item_66a",
      "9",
      "file_10",
      "item_1",
      "file_1"
    };
    
    items.Sort((a,b)=>new StringNum(a).CompareTo(new StringNum(b)));
    
    foreach (string s in items) Console.WriteLine(s);
    

    Output:

    9
    14
    26
    999
    file_1
    file_2
    file_10
    file_14
    item_1
    item_5
    item_66a
    item_66b
    

提交回复
热议问题