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 == '')
 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 = '';
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 }
View Code


另可参考:

http://www.codeproject.com/Articles/22175/Sorting-Strings-for-Humans-with-IComparer

感谢每一位阅读此篇文章的人,希望可以帮到你。

原文地址:https://www.cnblogs.com/congqiandehoulai/p/5504170.html