我有List<string>
多种尺码,比如 XS、S、M、L、XL、XXL、UK 10、UK 12 等
我想要的是强制顺序为上述顺序,无论列表中项目的顺序如何,我认为我需要一个 IComparable 运算符但不确定。
理想情况下,我希望有另一个具有正确顺序的列表,它可以引用它在列表中的“位置”并重新排序,如果它不存在,它将默认为 AZ
按照您希望它们的顺序创建一个尺寸数组,然后按衬衫尺寸在该数组中的位置对衬衫进行排序:
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]);
您可以直接使用OrderByDescending
+ ThenByDescending
:
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);
我使用是...Descending
因为 atrue
类似于 1 而 afalse
是 0。
你也可以这样做:
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;
}
}
用法:
var list = new List<string> { "S", "L", "XL", "L", "L", "XS", "XL", "XXXL", "XMLS", "XXL", "AM19" };
var result = list.OrderBy(size => size, new ShirtComparer());
对于不在列表中的值,它也应该默认为 AZ...
您还可以创建其他列表,并使用委托与排序一起使用,如果 size1 的索引 > size2 的索引,则返回。