加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

DataTable 给包含数字的字符串 排序

(2011-03-22 22:51:40)
标签:

datatable

字符串数字

排序

lambda

it

分类: C /C#

应用场景如下:

Index   Frequency

No.100  100

No.2    50

No.50   200

 

将上表存在DataTable中,要将DataTable的row按照Index进行排序,希望的顺序是:

No.2,No.50,No.100

如果简单的调用DataTable的sort功能,得到的结果是:

No.100,No.2,No.50

这是由于Sort将Index按照字符串的比较方法进行排序。

 

查了很多方法,有将Index字符串拆分成两部分,然后将数字部分提取出来进行排序的,

也有将每一行对应到一个类A的对象,加到List列表中,A继承IComparer接口,将Compare方法

重载,用对应的字段进行比较,得到想要的顺序。

 

我最理想的方法是仍将数据存在DataTable中,对DataTable进行排序的时候能够传入自定义的

比较器,各种查询资料,终于得到了想要的结果。

 

 public enum SortOrder
    {
        Ascending,
        Descending
    }
    public class RowComparer : IComparer<DataRow>
    {
        public Dictionary<int, SortOrder> SortColumns { get; set; }

        public int Compare(System.Data.DataRow x, System.Data.DataRow y)
        {
            int returnValue = 0;
            foreach (int key in SortColumns.Keys)
            {
                int compareResult;

                // Check for nulls
                if (x.ItemArray[key] == DBNull.Value
                           && y.ItemArray[key] == DBNull.Value)
                    compareResult = 0;
                else if (x.ItemArray[key] == DBNull.Value)
                    compareResult = -1;
                else if (y.ItemArray[key] == DBNull.Value)
                    compareResult = 1;
                else
                {
                    if (key == 0)
                    {
                        compareResult = ExCompare(x.ItemArray[key], y.ItemArray[key]);
                    }

                    else
                        // Compare anything else as a string
                        compareResult =
                             String.Compare(x.ItemArray[key].ToString(),
                                            y.ItemArray[key].ToString());
                }

                if (compareResult != 0)
                {
                    returnValue =
                       SortColumns[key] == SortOrder.Ascending ?
                                      compareResult : -compareResult;
                    break;
                }
            }
            return returnValue;
        }

 

        int ExCompare(Object x, Object y)
        {
            if (x == null || y == null)
                throw new ArgumentException("Parameters can't be null");

            string fileA = x as string;
            string fileB = y as string;
            char[] arr1 = fileA.ToCharArray();
            char[] arr2 = fileB.ToCharArray();

            int i = 0, j = 0;
            while (i < arr1.Length && j < arr2.Length)
            {
                if (char.IsDigit(arr1[i]) && char.IsDigit(arr2[j]))
                {
                    string s1 = "", s2 = "";
                    while (i < arr1.Length && char.IsDigit(arr1[i]))
                    {
                        s1 += arr1[i];
                        i++;
                    }
                    while (j < arr2.Length && char.IsDigit(arr2[j]))
                    {
                        s2 += arr2[j];
                        j++;
                    }

                    if (int.Parse(s1) > int.Parse(s2))
                    {
                        return 1;
                    }

                    if (int.Parse(s1) < int.Parse(s2))
                    {
                        return -1;
                    }

                }
                else
                {
                    if (arr1[i] > arr2[j])
                    {
                        return 1;
                    }

                    if (arr1[i] < arr2[j])
                    {
                        return -1;
                    }
                    i++;
                    j++;

                }

            }

            if (arr1.Length == arr2.Length)
            {
                return 0;
            }
            else
            {
                return arr1.Length > arr2.Length ? 1 : -1;
            }

       }
    }

在Main函数中调用如下语句:

            DataTable table = new DataTable();
            DataColumn index = new DataColumn("Index");
            DataColumn Frequency = new DataColumn("Frequency",typeof(int));
            DataColumn Temperature = new DataColumn("Temperature",typeof(double));

            table.Columns.Add(index);
            table.Columns.Add(Frequency);
            table.Columns.Add(Temperature);

            DataRow r1 = table.NewRow();
            r1["Index"] = "No.1000";
            r1["Frequency"] = "1000";
            r1["Temperature"] = "35.2";
            table.Rows.Add(r1);

            DataRow r2 = table.NewRow();
            r2["Index"] = "No.200";
            r2["Frequency"] = "500";
            r2["Temperature"] = "30";
            table.Rows.Add(r2);

            DataRow r3 = table.NewRow();
            r3["Index"] = "No.3";
            r3["Frequency"] = "700";
            r3["Temperature"] = "25";
            table.Rows.Add(r3);

            DataRow r4 = table.NewRow();
            r4["Index"] = "No.4";
            r4["Frequency"] = "700";
            r4["Temperature"] = "27";
            table.Rows.Add(r4);


            Dictionary<int, SortOrder> sortColumns =
                   new Dictionary<int, SortOrder>();
            //sortColumns.Add(2, SortOrder.Ascending);
            sortColumns.Add(0, SortOrder.Descending);

            RowComparer comp = new RowComparer();
            comp.SortColumns = sortColumns;

            var query3 = table.AsEnumerable().OrderBy(q => q, comp);
            DataView dv3 = query3.AsDataView();

 

得到的DataView就是我想要的排好序的结果啦。

不知道用正则表达式是不是可以解决这个问题,会不会更简单一些,有待探索。

下面是参考链接:

http://msmvps.com/blogs/deborahk/archive/2009/07/23/linq-sorting-a-datatable.aspx

http://blog.csdn.net/otong/archive/2008/02/19/2105965.aspx

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有