C# 自定义排序。所有 N 后跟 ASC 顺序

C# custom sorting. All Ns followed by ASC order

我正在使用 Infragistics XamDataGrid 开发 WPF 应用程序。我需要对几列进行排序才能像下面那样工作。

我会得到像 -1.00,N,1.73,N,-5.6,N,7 这样的值。我需要像下面这样排序

升序

N
N
-5.6
-1.00
1.73
7

降序

7
1.73
-1.00
-5.6
N
N

我只需要如下所示的自定义排序。无法获取我需要放置的内容。

public class MyCustomSort : IComparer
{
    public int Compare(object x, object y)
    {
        if (x == null || y == null) return 1;

        string x1, y1;            
        x1 = x.ToString();
        y1 = y.ToString();

        if (x1 == "N" || y1 == "N") return 1;

        return x1.CompareTo(y1);
    }
}

更新: 感谢 user2023861 。完成全面测试后,我会接受他的回答。我在下面更改了我的比较代码。我仍在测试,初步测试看起来不错。请让我知道您对此的看法。

public int Compare(object x, object y)
        {
            //put nulls first
            if (x == null) return 1;
            if (y == null) return -1;
            //put Ns second after nulls
            if (x.ToString() == "N") return -1;
            if (y.ToString() == "N") return 1;
            double doubleX;
            double doubleY;
            bool xParsed = Double.TryParse(x.ToString(), out doubleX);
            bool yParsed = Double.TryParse(y.ToString(), out doubleY);
            if(xParsed && yParsed)
            {
                // both X and Y are doubles
                return doubleX.CompareTo(doubleY);
            }

            return 1;
        }

我在下面标记了 user2023861 post 作为答案,因为它把我带到了正确的方向。我按照上面的方法更改了我的代码,到目前为止测试看起来不错。如果我遇到任何问题,我会更新这个。

谢谢大家

在此处了解 Compare 方法的 return 值 https://msdn.microsoft.com/en-us/library/system.collections.icomparer.compare(v=vs.110).aspx 总之,result < 0 表示 x 在前,result == 0 表示 x == y,result > 0 表示y 排在第一位。

例如,这一行:

if (x == null || y == null) return 1;

returns 结果表明 x 应该在 y 之后,因为结果大于零。

你的算法现在是这样的:

if x or y is null, y comes first
if x or y is "N", y comes first
otherwise compare x as a string to y as a string and return that

编辑:这是你的答案(确保对此进行了大量测试,我还没有尝试过)

public class MyCustomSort : IComparer
{
    public int Compare(object x, object y)
    {
        //put nulls first
        if (x == null) return 1;
        if (y == null) return -1;

        string x1, y1;            
        x1 = x.ToString();
        y1 = y.ToString();

        //put Ns second after nulls
        if (x1 == "N") return -1;
        if (y1 == "N") return 1;

        return x.CompareTo(y); //assuming these are doubles
    }
}

我在下面的快速控制台应用程序中进行了尝试,看起来很有效:

List<object> lst = new List<object> { "N", "N", -5.6, -1.00, 1.73, 7 };
            var result=
            lst.OrderByDescending(item =>
            {
                double val = 0;
                if (double.TryParse(item.ToString(), out val))
                {
                    return val;
                }
                return double.MaxValue; /*dummy number*/
            }).ToList();

 foreach(var i in result)
            {
                Console.WriteLine(i);
            }

下面是 OrderBy 和 OrderbyDescending 运算符执行片段时的屏幕截图:

input是字符串、双打和整数的女仆。您可以按类型对值进行分组,然后应用排序。试试这个代码:

var input = new object[] {-1.00, "N", 1.73, "N", -5.6, "N", 7};

// get all strings
var allN = input.Where(n => n is string);

// now filter numerics
var ints = input.Where(x => x is double).Cast<double>();
var doubles = input.Where(x => x is int).Select(x => (double) (int) x);

按类型拆分 input 后,您可以使用以下代码重新组合它:

var asc = allN.Concat(ints.Concat(doubles)
  .OrderBy(x => x).Cast<object>()).ToArray();
var desc = ints.Concat(doubles)
  .OrderByDescending(x => x).Cast<object>().Concat(allN).ToArray();