我已经尝试过寻找现有问题,但我不确定如何对此进行说明,而且这在任何地方都没有检索到结果:(
无论如何,我有一类"订购商品"具有不同的属性。这些订单商品用于服装,因此它们的尺寸(字符串)。
因为我是关于这些事情的OCD,所以我希望元素不是按字母数字值排序,而是按自定义顺序排序。
如果可能的话,我也希望不会对此自定义订单进行硬编码。
要将其细分,如果我有这些订单商品的清单,每个订单商品的尺寸如下:
2XL
S
5XL
M
使用字母数字排序,它将按以下顺序排列:
2XL
5XL
M
S
但我想将此列表排序为此顺序( 从最小尺寸到最大 ):
S
M
2XL
5XL
我能想到的唯一方法是使用硬编码的大小数组并按索引排序,然后当我需要获取大小值时,我可以获取大小顺序数组[i]值。但是,正如我所说,我希望这个命令不要硬编码。
我希望订单是动态的原因是订单项在运行时从硬盘上的文件加载,并且还在运行时由用户添加/编辑/删除,并且它们可能包含我没有硬编码,例如我可以从10XS到10XL一直硬编码但是如果有人增加尺寸" 110cm" (也称为中等),假设程序没有崩溃和烧毁,它将按照我不想要的顺序出现在某个地方。
我无法完全理解如何做到这一点。
答案 0 :(得分:5)
您可以直接使用OrderByDescending
+ ThenByDescending
:
sizes.OrderByDescending(s => s == "S")
.ThenByDescending( s => s == "M")
.ThenByDescending( s => s == "2XL")
.ThenByDescending( s => s == "5XL")
.ThenBy(s => s);
我使用...Descending
,因为true
类似于1而false
为0。
答案 1 :(得分:5)
此外,您可以在下方创建Dictionary<int, string>
并添加Key
为 Ordering order
。在Keys之间留出一些空白,以适应未来的新尺寸。例如:如果您要添加L (Large)
,则可以在不中断当前订单的情况下将新项目添加为{15, "L"}
。
Dictionary<int, string> mySizes = new Dictionary<int, string> {
{ 20, "2XL" }, { 1, "S" },
{ 30, "5XL" }, { 10, "M" }
};
var sizes = mySizes.OrderBy(s => s.Key)
.Select(s => new {Size = s.Value})
.ToList();
答案 2 :(得分:3)
我会将IComparer<string>
实施到您自己的TShirtSizeComparer
中。您可能需要执行一些正则表达式来获取所需的值。
IComparer<T>
是任何排序机制的绝佳界面。 .NET框架中的许多内置东西都使用它。它使排序可重复使用。
我真的建议将大小字符串解析为一个单独的对象,该对象具有大小编号和大小,然后用它进行排序。
答案 3 :(得分:1)
您需要在班级上实施IComparer
界面。您可以谷歌如何做到这一点,因为那里有很多例子
答案 4 :(得分:0)
你必须为此做一个简单的解析器。您可以在字符串中搜索XS XL和cm等元素,“如果你过滤掉你的单位。那么你可以获得整数值。如果你有,你确实可以使用IComparer对象,但它没有没有那么大的优势。
答案 5 :(得分:0)
我会用Size创建一个类,很可能你将来需要添加更多功能。我添加了大小的全名,但您也可以添加宽度和长度等变量,以及英寸或厘米的转换器。
private void LoadSizes()
{
List<Size> sizes = new List<Size>();
sizes.Add(new Size("2X-Large", "2XL", 3));
sizes.Add(new Size("Small", "S", 1));
sizes.Add(new Size("5X-Large", "5XL", 4));
sizes.Add(new Size("Medium", "M", 2));
List<string> sizesShortNameOrder = sizes.OrderBy(s => s.Order).Select(s => s.ShortName).ToList();
//If you want to use the size class:
//List<Size> sizesOrder = sizes.OrderBy(s => s.Order).ToList();
}
public class Size
{
private string _name;
private string _shortName;
private int _order;
public string Name
{
get { return _name; }
}
public string ShortName
{
get { return _shortName; }
}
public int Order
{
get { return _order; }
}
public Size(string name, string shortName, int order)
{
_name = name;
_shortName = shortName;
_order = order;
}
}
答案 6 :(得分:0)
我使用基类TShirtSizeComparer
实现了Comparer<object>
。当然,您必须根据可用的尺寸和对象进行调整:
public class TShirtSizeComparer : Comparer<object>
{
// Compares TShirtSizes and orders them by size
public override int Compare(object x, object y)
{
var _sizesInOrder = new List<string> { "None", "XS", "S", "M", "L", "XL", "XXL", "XXXL", "110 cl", "120 cl", "130 cl", "140 cl", "150 cl" };
var indexX = -9999;
var indexY = -9999;
if (x is TShirt)
{
indexX = _sizesInOrder.IndexOf(((TShirt)x).Size);
indexY = _sizesInOrder.IndexOf(((TShirt)y).Size);
}
else if (x is TShirtListViewModel)
{
indexX = _sizesInOrder.IndexOf(((TShirtListViewModel)x).Size);
indexY = _sizesInOrder.IndexOf(((TShirtListViewModel)y).Size);
}
else if (x is MySelectItem)
{
indexX = _sizesInOrder.IndexOf(((MySelectItem)x).Value);
indexY = _sizesInOrder.IndexOf(((MySelectItem)y).Value);
}
if (indexX > -1 && indexY > -1)
{
return indexX.CompareTo(indexY);
}
else if (indexX > -1)
{
return -1;
}
else if (indexY > -1)
{
return 1;
}
else
{
return 0;
}
}
}
要使用它,你只需要一个List或你的对象是什么和做什么:
tshirtList.Sort(new TShirtSizeComparer());
您拥有的订单&#34;硬编码&#34;优先考虑,其余部分放在后面。
我确信它可以做得更聪明,更通用,以避免硬编码。你可以,例如寻找以&#34; S&#34;然后检查多少X(例如XXS)或X之前的数字(例如2XS)并按此排序,然后重复&#34; L&#34;或者其他&#34;主要尺寸&#34;。