I am working on WPF application using Infragistics XamDataGrid. I have few columns that I need to sort to work like below.
I will have values like -1.00,N,1.73, N, -5.6, N, 7.. I need sort to be like below
Asc order
N
N
-5.6
-1.00
1.73
7
Desc order
7
1.73
-1.00
-5.6
N
N
I just need custom sort like below. Unable to get what I need to put.
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);
}
}
UPDATE: Thanks to user2023861 . I will accept his answer after I finish my thorough testing. I changed my Compare code below. I am still testing and initial testing looks good. Please let me know your views on this.
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;
}
I marked user2023861 post below as answer since it took me into right direction. I changed my code as per above and testing so far looks good. I will update this if I encounter any issues.
Thanks all.
Read about the return values of the Compare method here https://msdn.microsoft.com/en-us/library/system.collections.icomparer.compare(v=vs.110).aspx In summary, result < 0 means x is first, result == 0 means x == y, and result > 0 means y comes first.
For instance, this line:
if (x == null || y == null) return 1;
returns a result stating that x
should come after y
because the result is greater than zero.
What your algorithm is doing now is this:
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
Edit: here's your answer (make sure to test this plenty, I haven't tried it)
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
}
}
I tried below in quick console application and looks it works :
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);
}
Below is screen shot when snippet executed by OrderBy and OrderbyDescending operator :
You input
are maid from strings, doubles and ints. You can group values by type and then apply sorting. Try this code:
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);
After splitting input
by types you can recombine it with this code:
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();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.