Reputation: 295
I have a problem when sorting a generic list in C#
I have a List<MyObjects> myList
, and MyObject
has a string property.
Now it looks like this when sorting descending
2.4.88
2.4.70
2.4.164 -> this is wrong
2.4.15
How do I sort my list?
I have tried:
myList.sort(delegate(MyObjects obj1, MyObjects obj2)
{
return obj2.version.CompareTo(obj1.version);
});
Its not an option to use Linq (older framework)
UPDATE: My list can also contains N/A
Upvotes: 4
Views: 2390
Reputation: 11066
If your string pattern fits the .Net version class then convert it to a Version object and compare.
Upvotes: 1
Reputation: 7584
You cannot compare as strings, because obviously thats the proper string sorting. You need to parse to numbers or to an instance of the Version
class:
myList.sort(delegate(MyObjects obj1, MyObjects obj2)
{
return new Version(obj2.version).CompareTo(new Version(obj1.version));
});
Upvotes: 3
Reputation: 158081
I had to do natural sorting a while ago. Don't remember where I found the code, but stuck it on my blog for future reference: http://www.geekality.net/2009/03/02/natural-sorting
Here's the code:
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
namespace NaturalSort
{
public sealed class NaturalStringComparer : IComparer<string>
{
private readonly int modifier = 1;
public NaturalStringComparer(bool descending)
{
if (descending)
modifier = -1;
}
public NaturalStringComparer()
:this(false) {}
public int Compare(string a, string b)
{
return SafeNativeMethods.StrCmpLogicalW(a ?? "", b ?? "") * modifier;
}
}
public sealed class NaturalFileInfoComparer : IComparer<FileInfo>
{
public int Compare(FileInfo a, FileInfo b)
{
return SafeNativeMethods.StrCmpLogicalW(a.Name ?? "", b.Name ?? "");
}
}
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
}
You'd use it along these lines:
myList.Sort(new NaturalStringComparer(true));
Upvotes: 3
Reputation: 2192
Can you describe how it is wrong. Looks like it is perfectly placed in order. However, just a random suggestion, if you are sure of format you can break the string and convert to number to check this kind of stuff.
Upvotes: -1
Reputation: 1062965
Perhaps sort via Version?
return (Version.Parse(obj2.version)).CompareTo(Version.Parse(obj1.version));
of course, it will be cheaper if you do the parsing once and once only (maybe make version
a Version
instead of a string
)
Upvotes: 2