如何正确排序DataTable

时间:2017-09-05 12:48:41

标签: c# regex linq sorting icomparer

我正在尝试对字符串数字列进行排序,例如N1,N10,N100,N2和我期待结果N1,N2,N10,N100,但排序不起作用,我得到相同的值N1,N10,N100,N2。

我写了以下代码。

static class ExtensionMethod
{
    public static DataTable SortAlphaNumeric(this DataTable datatable, string columnName)
    {
        return datatable.AsEnumerable()
                  .OrderBy(r => r.Field<String>(columnName), new CustomComparer())
                  .CopyToDataTable();
    }
}

public class CustomComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        var numberX = Regex.Match(x, @"\d+").Value;
        var numberY = Regex.Match(y, @"\d+").Value;

        var alphaX = Regex.Match(x, @"[^a-z]").Value;
        var alphaY = Regex.Match(y, @"[^a-z]").Value;

        if (alphaX.CompareTo(alphaY) == 0)
            return numberX.CompareTo(numberY);
        else if (alphaX.CompareTo(alphaY) < 0)
            return -1;
        return 1;            
    }
}

// Code example
class TestExample
{
    public void Test()
    {
        var dt = new DataTable();
        dt.Columns.Add("AlphaNumeric", Type.GetType("System.String"));
        var row = dt.NewRow();
        row["AlphaNumeric"] = "N1";
        dt.Rows.Add(row);
        row = dt.NewRow();
        row["AlphaNumeric"] = "N10";
        dt.Rows.Add(row);
        row = dt.NewRow();
        row["AlphaNumeric"] = "N100";
        dt.Rows.Add(row);
        row = dt.NewRow();
        row["AlphaNumeric"] = "N2";
        dt.Rows.Add(row);

        var orderedDt = dt.SortAlphaNumeric("AlphaNumeric");
    }
}

3 个答案:

答案 0 :(得分:3)

您的比较者的变化:

var numberX = int.Parse(Regex.Match(x, @"\d+").Value);
var numberY = int.Parse(Regex.Match(y, @"\d+").Value);

答案 1 :(得分:1)

我使用(?<alpha>[A-Za-z])(?<number>\d+)作为正则表达式并比较alpha(字符串比较),然后,如果相等,int.Parse number并比较(整数比较)

只提供两个正则表达式执行而不是四个(可能正在编译正则表达式并将其置于静态字段中也会使其更快),如果您比较,2将小于10实际数字。如果你不解析数字,你可以跳过整个正则表达式,只做一个字符串比较。

答案 2 :(得分:0)

如果数字sheme是确定的(总是一个字符串+一个整数),你可以简单地将它们存储在两个单独的字段中(理想情况下是在DB中。毕竟,组合键是一个东西)。然后是&#34;首先按字符串排序,编号为2&#34;。

如果不是,那么事情就会变得艰难。你想要的是Windows对文件进行的非常不寻常的排序。除了自定义正则表达式解决方案之外(但如果它是确定性的,你可以使用2个或更多字段),那么会有StrCmpLogicalW。但是那个是非托管的,它的行为在Windows之间变化(它是#34;规范&#34;它运行的Windows的排序,但在Windows版本之间排序变化)。