c#实现自然排序效果,按1,2,11而不是1,11,12,区分字母文字和数字
排序有时候要考虑后缀。这样看起来比较自然。
参考了codeproject上一篇文章:http://www.codeproject.com/Articles/22978/Implementing-the-NET-IComparer-interface-to-get-a
然后自己写了个简单的,考虑到主要思想是上面那个文章上的,所以不做太多解释。代码如下:
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Text.RegularExpressions; 7 8 namespace StringOrder 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 string[] array = new string[] { "2.1", "2.001" }; 15 16 string[] array2 = array.OrderBy(a => a, new StringCompare1()).ToArray(); 17 Console.Read(); 18 19 20 } 21 } 22 public class StringCompare1 : IComparer<string> 23 { 24 public int Compare(string x, string y) 25 { 26 27 StringParser sx = new StringParser(x); 28 StringParser sy = new StringParser(y); 29 while (sx.TokenType != StringParser.ETokenType.Nothing || sy.TokenType != StringParser.ETokenType.Nothing) 30 { 31 if (sx.TokenType == StringParser.ETokenType.Numberic && sy.TokenType == StringParser.ETokenType.Numberic) 32 { 33 return decimal.Compare(sx.DoubleValue,sy.DoubleValue); 34 } 35 if (string.Compare(sx.StringValue, sy.StringValue) != 0) 36 { 37 return string.Compare(sx.StringValue, sy.StringValue); 38 } 39 else 40 { 41 sx.NextToken(); 42 sy.NextToken(); 43 } 44 } 45 return 0; 46 } 47 } 48 49 public class StringParser 50 { 51 private string _value; 52 private char _curChar; 53 private int _curIndex = 0; 54 private int _length; 55 private ETokenType _tokenType = ETokenType.Character; 56 public ETokenType TokenType { get { return _tokenType; } } 57 58 private string _stringValue; 59 public string StringValue { get { return _stringValue; } } 60 61 private decimal _doubleValue; 62 public decimal DoubleValue { get { return _doubleValue; } } 63 64 65 public StringParser(string val) 66 { 67 _value = val; 68 _length = val.Length; 69 NextChar(); 70 NextToken(); 71 } 72 73 public void NextToken() 74 { 75 if (_curChar == '\0') 76 { 77 _tokenType = ETokenType.Nothing; 78 _stringValue = null; 79 } 80 else if (char.IsDigit(_curChar)) 81 { 82 int startIndex = _curIndex; 83 while (char.IsDigit(_curChar) || _curChar == '.') 84 { 85 NextChar(); 86 } 87 string temp = _value.Substring(startIndex-1, _length - startIndex+1); 88 if (decimal.TryParse(temp, out _doubleValue)) 89 { 90 _tokenType = ETokenType.Numberic; 91 } 92 else 93 { 94 _tokenType = ETokenType.Character; 95 } 96 _stringValue = temp; 97 } 98 else if (char.IsLetter(_curChar)) 99 { 100 _tokenType = ETokenType.Character; 101 int startIndex = _curIndex; 102 while (char.IsLetter(_curChar)) 103 { 104 NextChar(); 105 } 106 _stringValue = _value.Substring(startIndex-1,_curIndex-startIndex); 107 } 108 else 109 { 110 NextChar(); 111 } 112 } 113 114 private void NextChar() 115 { 116 if (_curIndex >= _length) 117 { 118 _curChar = '\0'; 119 return; 120 } 121 else 122 { 123 _curChar = _value[_curIndex]; 124 _curIndex += 1; 125 } 126 127 } 128 public enum ETokenType 129 { 130 Nothing, 131 Character, 132 Numberic, 133 } 134 } 135 }
另可参考:
http://www.codeproject.com/Articles/22175/Sorting-Strings-for-Humans-with-IComparer
感谢每一位阅读此篇文章的人,希望可以帮到你。