从http://www.interact-sw.co.uk/iangblog/2007/12/13/natural-sorting获取代码并对其进行修改,使其按字符串长度(按数字拆分后)排序,然后按自然排序。限制是,如果您确实有不同名称的工作表,那么您的工作表也将按字符串长度排序,而不是按 asciinerical 排序。
public class ExcelNameComparer<T> : IComparer<IEnumerable<T>>
{
/// <summary>
/// Create a sequence comparer using the default comparer for T.
/// </summary>
public ExcelNameComparer()
{
comp = Comparer<T>.Default;
}
/// <summary>
/// Create a sequence comparer, using the specified item comparer
/// for T.
/// </summary>
/// <param name="comparer">Comparer for comparing each pair of
/// items from the sequences.</param>
public ExcelNameComparer(IComparer<T> comparer)
{
comp = comparer;
}
/// <summary>
/// Object used for comparing each element.
/// </summary>
private IComparer<T> comp;
/// <summary>
/// Compare two sequences of T.
/// </summary>
/// <param name="x">First sequence.</param>
/// <param name="y">Second sequence.</param>
public int Compare(IEnumerable<T> x, IEnumerable<T> y)
{
using (IEnumerator<T> leftIt = x.GetEnumerator())
using (IEnumerator<T> rightIt = y.GetEnumerator())
{
while (true)
{
bool left = leftIt.MoveNext();
bool right = rightIt.MoveNext();
if (!(left || right)) return 0;
if (!left) return -1;
if (!right) return 1;
int lengthResult = leftIt.Current.ToString().Length.CompareTo(rightIt.Current.ToString().Length);
if (lengthResult != 0) return lengthResult;
int itemResult = comp.Compare(leftIt.Current, rightIt.Current);
if (itemResult != 0) return itemResult;
}
}
}
Func<string, object> convert = str =>
{
try { return int.Parse(str); }
catch { return str; }
};
现在运行实际排序:
var lst = new List<string> { "Sheet1!$A$9:$B$172", "Sheet1!$AY$77:$AZ$172", "Sheet1!$E$41:$F$172", "Sheet1!$A$10:$B$172", "Sheet1!$A$1:$B$172" };
var sorted = lst.OrderBy(
str => Regex.Split(str.Replace(" ", ""), "([0-9]+)").Select(convert),
new ExcelNameComparer<object>());
foreach (var sort in sorted)
{
System.Diagnostics.Debug.Print(sort);
}
产量:
Sheet1!$A$1:$B$172
Sheet1!$A$9:$B$172
Sheet1!$A$10:$B$172
Sheet1!$E$41:$F$172
Sheet1!$AY$77:$AZ$172