I have a List<string>
of sizes, say XS, S, M, L, XL, XXL, UK 10, UK 12 etc
What I want is to force the order to be that of above, regardless of the order of items in the list, I think I need a IComparable operator but unsure.
Ideally I want to have another List with the correct order in which it can reference it's 'place' in the list and re-sort itself, if it doesn't exist it will default to A-Z
You could also do something like this:
public class ShirtComparer : IComparer<string>
{
private static readonly string[] Order = new[] { "XS", "S", "M", "L", "XL", "XXL", "UK10", "UK12" };
public int Compare(string x, string y)
{
var xIndex = Array.IndexOf(Order, x);
var yIndex = Array.IndexOf(Order, y);
if (xIndex == -1 || yIndex == -1)
return string.Compare(x, y, StringComparison.Ordinal);
return xIndex - yIndex;
}
}
Usage:
var list = new List<string> { "S", "L", "XL", "L", "L", "XS", "XL", "XXXL", "XMLS", "XXL", "AM19" };
var result = list.OrderBy(size => size, new ShirtComparer());
It should also default to A-Z for values not in the list...
Create an array of sizes in the order you want them to be in, then sort the shirts by the position of their sizes in that array:
string[] sizes = new [] {"XS", "S", "M", "L", "XL", "XXL", "UK 10", "UK 12"};
var shirtsInOrder = shirts
.OrderBy(s=>sizes.Contains(s) ? "0" : "1") // put unmatched sizes at the end
.ThenBy(s=>Array.IndexOf(sizes,s)) // sort matches by size
.ThenBy(s=>s); // sort rest A-Z
var order = new string[] { "XS", "S", "M", "L", "XL", "XXL", "UK10", "UK12" };
var orderDict = order.Select((c, i) => new { sze = c, ord = i })
.ToDictionary(o => o.sze, o => o.ord);
var list = new List<string> { "S", "L", "XL", "L", "L", "XS", "XL" };
var result = list.OrderBy(item => orderDict[item]);
You can use OrderByDescending
+ ThenByDescending
directly:
sizes.OrderByDescending(s => s == "XS")
.ThenByDescending( s => s == "S")
.ThenByDescending( s => s == "M")
.ThenByDescending( s => s == "L")
.ThenByDescending( s => s == "XL")
.ThenByDescending( s => s == "XXL")
.ThenByDescending( s => s == "UK 10")
.ThenByDescending( s => s == "UK 12")
.ThenBy(s => s);
I use ...Descending
since a true
is similar to 1 whereas a false
is 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With