Reputation:
I have an extension class that is converting an Observable collection to list and performing an order by. This logic is working but I need it to sort Alpha-numeric as well. E.g.
In lieu of A1 A10 A2 A3 should be A1 A2 A3 A10.
What is the best way to go about this?
<pre>
public static void Sort<T>(this ObservableCollection<T> collection, Comparison<T> comparison)
{
var comparer = new Comparer<T>(comparison);
List<T> sorted = collection.OrderBy(x => x, comparer).ToList();
for (int i = 0; i < sorted.Count(); i++)
collection.Move(collection.IndexOf(sorted[i]), i);
}
internal class Comparer<T> : IComparer<T>
{
private readonly Comparison<T> comparison;
public Comparer(Comparison<T> comparison)
{
this.comparison = comparison;
}
#region IComparer<T> Members
public int Compare(T x, T y)
{
return comparison.Invoke(x, y);
}
}
</pre>
Upvotes: 0
Views: 970
Reputation: 166
Parse the string
into two parts, the alpha part and the number part. Put the number part into an int
, and then compare the int part only when the alpha part is a tie.
public int Compare(string left, string right) {
string leftAlpha;
int leftNum;
string rightAlpha;
int rightNum;
GetParts(left, out leftAlpha, out leftNum);
GetParts(right, out rightAlpha, out rightNum);
if (leftAlpha != rightAlpha) {
return String.Compare(leftAlpha, rightAlpha);
}
else {
return leftNum.CompareTo(rightNum);
}
}
private void GetParts(string str, out string alpha, out string num) {
alpha = str.Substring(0, 1);
string numStr = str.Substring(1);
num = Int32.Parse(numStr);
}
If you can find a way to expose those two parts as properties on a class, you might be best off using a CollectionView to bind to. Where the SourceCollection
is your ObservableCollection
, and then add SortDescriptions
which correspond to the properties on the class. That could be overkill, but does have a lot of benefits like inserting new elements directly into the right position. You won't have to do any sorting on the collections explicitly at all.
Upvotes: 1