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();
我正在使用 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();