问题
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
回答1:
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
回答2:
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]);
回答3:
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.
回答4:
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...
回答5:
You can also create other list, and use a delegate to use with the sort, where you return if the index of size1 > index of size2.
来源:https://stackoverflow.com/questions/65009459/linq-order-list-from-comparing-list-with-string-value