简体   繁体   English

列表<string>复杂排序

[英]List<string> complex sorting

I have a List<string> of sizes, say XS, S, M, L, XL, XXL, UK 10, UK 12 etc我有一个List<string>尺寸,比如 XS、S、M、L、XL、XXL、UK 10、UK 12 等

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.我想要的是强制顺序为上面的顺序,无论列表中项目的顺序如何,我想我需要一个 IComparable 运算符但不确定。

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 AZ理想情况下,我希望有另一个具有正确顺序的列表,它可以引用它在列表中的“位置”并重新排序,如果它不存在,它将默认为 AZ

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:您可以直接使用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);

I use ...Descending since a true is similar to 1 whereas a false is 0.我使用...Descending因为true类似于 1 而false是 0。

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 AZ for values not in the list...对于不在列表中的值,它也应该默认为 AZ...

您还可以创建其他列表,并使用委托与排序一起使用,如果 size1 的索引 > size2 的索引,则返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM