【问题标题】:How to sort C# Datatable with empty column values at the end如何在末尾使用空列值对 C# Datatable 进行排序
【发布时间】:2020-07-29 06:46:47
【问题描述】:

我有一个包含 1000 行的 C# 数据表。但主要的 200 行有空值(多列)。过滤器会发生在这些列上,作为最后占用的空值。我希望输出将在带有过滤器的表或新表中发生,但不是作为 linq 行。请帮帮我

图片说话更多,请参考此以更好地理解:

【问题讨论】:

  • 您必须先对列中是否有数据的行进行排序,然后按行列值排序
  • 使用 LINQ 将是一个简单的orders.OrderBy(x => string.IsNullOrEmpty(x))(或string.IsNullOrWhiteSpace)。如果您也想按内容订购,只需在之后添加.ThenBy。如果没有 LINQ,您将不得不实现自定义 IComparer<string>。这是你想要的还是你指的是不同的东西?
  • @MyNameIsDND 我的回答能解决你的问题吗?

标签: c# .net linq datatable dataview


【解决方案1】:

这里有两件事你应该考虑:

  1. 空值”:要对后面跟着空值列的项目进行排序,您需要.OrderBy(s => String.IsNullOrEmpty(s["OrderNo"].ToString()))
  2. 订单无格式”:要对自定义订单号进行排序,您需要使用IComparer<string>。正如您在问题中显示的那样,我假设Order No 的格式可以是XXXXXXXXX-XXXX

所以你需要首先OrderBy 空值ThenBy 你的自定义IComparer<string> 是这样的:

public class OrderNoComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        int xFirstValue = 0;
        int xSecondValue = 0;

        int yFirstValue = 0;
        int ySecondValue = 0;

        if (x.Contains("-"))
        {
            xFirstValue = Convert.ToInt32(x.Split(new char[] { '-' })[0]);
            xSecondValue = Convert.ToInt32(x.Split(new char[] { '-' })[1]);
        }
        else
        {
            xFirstValue = Convert.ToInt32(x);
        }

        if (y.Contains("-"))
        {
            yFirstValue = Convert.ToInt32(y.Split(new char[] { '-' })[0]);
            ySecondValue = Convert.ToInt32(y.Split(new char[] { '-' })[1]);
        }
        else
        {
            yFirstValue = Convert.ToInt32(y);
        }


        if (xFirstValue > yFirstValue)
        {
            return 1;
        }
        else if (xFirstValue < yFirstValue)
        {
            return -1;
        }
        else //means equal
        {
            if (xSecondValue > ySecondValue)
            {
                return 1;
            }
            else if (xSecondValue == ySecondValue)
            {
                return 0;

            }
            else
            {
                return -1;
            }
        }
    }
}

完整的例子在这里:

DataTable dtOrder = new DataTable();
dtOrder.Columns.Add("OrderNo");

var dr1 = dtOrder.NewRow();
dr1["OrderNo"] = "";
dtOrder.Rows.Add(dr1);

var dr2 = dtOrder.NewRow();
dr2["OrderNo"] = "569-875";
dtOrder.Rows.Add(dr2);

var dr3 = dtOrder.NewRow();
dr3["OrderNo"] = "569975";
dtOrder.Rows.Add(dr3);

var dr4 = dtOrder.NewRow();
dr4["OrderNo"] = "569865";
dtOrder.Rows.Add(dr4);

var dr5 = dtOrder.NewRow();
dr5["OrderNo"] = "569-975";
dtOrder.Rows.Add(dr5);

var dr6 = dtOrder.NewRow();
dr6["OrderNo"] = "569-875";
dtOrder.Rows.Add(dr6);


var result = dtOrder.AsEnumerable().AsQueryable()
                .OrderBy(s => String.IsNullOrEmpty(s["OrderNo"].ToString()))
                .ThenBy(o => o["OrderNo"].ToString(), new OrderNoComparer())
                .ToList();

foreach (var item in result)
{
    Console.WriteLine(item["OrderNo"]);
}

那么输出就会像你预期的那样:

569-875
569-875
569-975
569865
569975

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2018-10-28
    • 2020-08-17
    相关资源
    最近更新 更多