List complex sorting

后端 未结 5 1268
攒了一身酷
攒了一身酷 2020-11-27 07:37

I have a List 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 th

相关标签:
5条回答
  • 2020-11-27 08:21

    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.

    0 讨论(0)
  • 2020-11-27 08:32

    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.

    0 讨论(0)
  • 2020-11-27 08:38

    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
    
    0 讨论(0)
  • 2020-11-27 08:40
    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]);
    
    0 讨论(0)
  • 2020-11-27 08:43

    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...

    0 讨论(0)
提交回复
热议问题