1

我试过寻找一个现有的问题,但不知道如何表达这个问题,这在任何地方都没有检索到任何结果:(

无论如何,我有一类具有不同属性的“订单项”。这些订单商品用于服装,因此它们将具有尺寸(字符串)。

因为我对这类事情有强迫症,所以我希望元素不是按字母数字值的大小排序,而是按自定义顺序的大小排序。

如果可能的话,我也希望不要对这个自定义订单进行硬编码。

分解它,如果我有一个这些订单项目的列表,每个项目都有一个尺寸,如下所示:

2XL
S
5XL
M

使用字母数字排序,它将按以下顺序排列:

2XL
5XL
M
S

但我想将此列表排序为以下顺序(从最小到最大):

S
M
2XL
5XL

我能想到的唯一方法是拥有一个硬编码的大小数组并按它们的索引排序,然后当我需要获取大小值时,我可以获取大小顺序数组 [i] 值。但是,正如我所说,我希望这个订单不要被硬编码。

我希望订单是动态的原因是订单项目是在运行时从硬盘上的文件加载的,并且还由用户在运行时添加/编辑/删除,它们可能包含我没有的大小t 硬编码,例如,我可以从 10XS 一直硬编码到 10XL,但如果有人添加尺寸“110cm”(又名 Medium),它会按照我不希望的顺序出现在某个地方,假设程序不会崩溃和烧毁。

我无法完全理解如何做到这一点。

4

7 回答 7

5

您可以直接使用OrderByDescending+ ThenByDescending

sizes.OrderByDescending(s => s == "S")
     .ThenByDescending( s => s == "M")
     .ThenByDescending( s => s == "2XL")
     .ThenByDescending( s => s == "5XL")
     .ThenBy(s => s);

我使用是...Descending因为 atrue类似于 1 而 afalse是 0。

于 2013-03-05T13:10:59.213 回答
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();
于 2013-03-05T13:23:15.873 回答
3

我会实施IComparer<string>到你自己的TShirtSizeComparer. 您可能需要执行一些正则表达式才能获得所需的值。

IComparer<T>是任何排序机制的绝佳接口。.NET 框架中的许多内置内容都使用它。它使排序可重用

我真的建议将大小字符串解析为一个单独的对象,该对象具有大小编号和大小大小,然后用它进行排序。

于 2013-03-05T13:10:34.160 回答
1

您需要IComparer在您的类上实现接口。您可以谷歌如何做到这一点,因为那里有很多例子

于 2013-03-05T13:10:05.473 回答
0

您必须为此制作一个简单的解析器。您可以在字符串中搜索 XS XL 和 cm" 等元素,然后过滤掉您的单位。然后您可以获得作为值的整数。如果您确实可以使用 IComparer 对象,但它没有没有那么大的优势。

于 2013-03-05T13:23:23.297 回答
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;
    }
}
于 2013-03-05T14:31:30.670 回答
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());

您“硬编码”的顺序优先,其余的放在后面。

我确信它可以做得更聪明,更通用,以避免对所有内容进行硬编码。例如,您可以查找以“S”结尾的尺寸,然后检查有多少 X(例如 XXS)或 X 之前的数字(例如 2XS)并按此排序,然后重复“L”以及其他“主要尺寸” .

于 2017-12-06T13:44:49.983 回答