2013-03-05 3 views
1

Я попытался, глядя на существующий вопрос, но не был уверен, как фраза это и это не извлекается никаких результатов в любом месте :(Как сортировать строки по другому значению

Во всяком случае, у меня есть класс «ордена Элементы ", которые имеют разные свойства. Эти предметы заказа предназначены для одежды, поэтому они будут иметь размер (строка).

Поскольку я являюсь ОКР по этим вещам, я хотел бы иметь элементы , отсортированные не по размеры как буквенно-цифровые значения, но по размерам в произвольном порядке.

Я также хотел бы t, если это возможно, на заказ.

Чтобы разорвать его, если у меня есть список этих элементов порядка с размерами в каждом из них, например, так:

2XL 
S 
5XL 
M 

С буквенно-цифровой сортировки это было бы в таком порядке:

2XL 
5XL 
M 
S 

Но я хотел бы, чтобы отсортировать этот список в таком порядке (от меньшего к величине):

S 
M 
2XL 
5XL 

Единственный способ, которым я могу это сделать, - это иметь жестко закодированный массив размеров и сортировать по их индексу, а затем, когда мне нужно захватить значение размера, я могу захватить массив порядка размера [i ] стоимость. Но, как я уже сказал, я бы предпочел, чтобы этот приказ не был жестко закодирован.

Причина, по которой я хочу, чтобы заказ был динамическим, элементы заказа загружаются из файлов на жестком диске во время выполнения, а также добавляются/редактируются/удаляются пользователем во время выполнения и могут содержать размер что я не жестко закодирован, например, я мог бы жестко закодировать весь путь от 10XS до 10XL, но если кто-то добавит размер «110 см» (он же Medium), он появится где-то в том порядке, в котором я не буду хотите, чтобы программа, если программа не сбой и не горит.

Я не могу оборачивать голову, как это сделать.

+1

Когда товары загружаются, где они загружаются? В БД? Вы не могли бы применить здесь индекс заказа? – Liam

+0

Я просто ответил на аналогичный вопрос, вот мой ответ: http://stackoverflow.com/questions/15223213/link-two-lists-of-different-types-together/15223452#15223452 – Nolonar

+1

Если кто-то добавляет 110 см, как вы знать его значение? –

ответ

5

Кроме того, вы можете создать Dictionary<int, string> и добавить Key, какOrdering order ниже. Оставляя некоторые пробелы между клавишами, чтобы разместить новые размеры для будущего. Например: если вы хотите добавить 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(); 
+0

Это может сработать! Благодаря! – cjk84

+0

@CliftonJKent я бы все еще обернул это в «IComparer », чтобы его можно было использовать повторно. –

+0

@ DanielA.White Да, это имеет смысл. Возможно, я мог бы попытаться разобрать каждый размер на целочисленное значение и использовать это как ключ. – cjk84

1

Вам необходимо реализовать интерфейс IComparer на вашем классе. Вы можете сделать это, так как есть много примеров.

+0

Я посмотрел на IComparer, не так ли это было жестко закодированное решение? – cjk84

+1

@ CliftonJKent существует некоторая жесткая кодировка с помощью 'Icomparer', но вы можете поместить логику в таблицу решений. –

3

Я бы ввел IComparer<string> в ваш собственный TShirtSizeComparer. Возможно, вам придется выполнять некоторые регулярные выражения, чтобы получить нужные значения.

IComparer<T> - отличный интерфейс для любого механизма сортировки. Это использует множество встроенных материалов в платформе .NET. Это делает сортировку многоразовой.

Я бы действительно предложил разбор строки размера в отдельный объект с размером и размером, а затем сортировкой с этим.

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.

+3

у этого было бы много накладных расходов. –

+1

Разве этот «жесткий код» не упорядочен? Который ОП пытается избежать? – Liam

+0

Я предполагаю, что это то, что вы имели в виду с жестким кодом. @ DanielA.White: Каковы накладные расходы? Это похоже на 'if-else' или в sql' ORDER BY DESC, B DESC, C DESC, ... ' –

0

Для этого вам нужно будет сделать простой синтаксический анализатор. Вы можете искать внутри строки для таких элементов, как XS XL и cm ", если вы затем отфильтровываете это, у вас есть свой блок. Тогда вы можете получить целое число, которое является значением. Если у вас есть, что вы действительно можете использовать объект IComparer, но он не работает

0

Я бы выбрал класс из «Размер», скорее всего, вам нужно будет добавить в него больше функций в будущем. Я добавил полное имя размера, но вы Можно также добавить переменные, такие как ширина и длина, и конвертеры для дюймов или см.

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; 
    } 
} 
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; 
     } 
    } 
} 

Для этого вам просто есть список или что-то ваш объект и сделать:

tshirtList.Sort(new TShirtSizeComparer()); 

заказ вы должны «жестко» имеет приоритет, а остальное ставится на назад.

Я уверен, что это можно сделать немного умнее и более обобщенно, чтобы избежать жесткого кодирования всего. Вы можете, например, найдите размеры, заканчивающиеся на «S», а затем проверьте, сколько X (например, XXS) или число до X (например, 2XS), и отсортируйте их, а затем повторите для «L» и, возможно, других «основных размеров».

Смежные вопросы