Сортировать список по ссылке C # - PullRequest
2 голосов
/ 20 февраля 2012

У меня есть List<Unit>, где Unit содержит Name и Value. В этом объекте я храню информацию о размерах одежды Name содержит имена размеров (S, M, L, XL ..), а Value содержит количество таких размеров.

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

Unit(M,3)
Unit(S,1)
Unit(XXL,2)
Unit(L,2)

Я бы хотел отсортировать список так, чтобы он выглядел примерно так:

Unit(S,1)
Unit(M,3)
Unit(L,2)
Unit(XXLL,2)

Я не могу заказать строку ASCE или DESC, поскольку она M предшествует S и так далее. Тогда я подумал, что мог бы создать ссылочный массив с правильным порядком (XXS, XS, S, M, L, XL, XXL, XXXL), но как я могу отсортировать свой список по ссылке.

Или есть другие умные способы сделать это?

Update

Спасибо за все хорошие ответы, я нашел решение Enum, и оно, наконец, выглядит так:

public class Unit
{
    public Unit()
    {
    }

    public Unit(string name, int value)
    {
        Value = value;
        SizeCode = AssignSizeCode(name);
    }

    public SizeCode SizeCode { get; set; }
    public int Value { get; set; }

    private SizeCode AssignSizeCode(string name)
    {
        switch (name)
        {
            case "XXS":
                return SizeCode.XXS;
            case "XS":
                return SizeCode.XS;
            case "S":
                return SizeCode.S;
            case "M":
                return SizeCode.M;
            case "L":
                return SizeCode.L;
            case "XL":
                return SizeCode.XL;
            case "XXL":
                return SizeCode.XXL;
            case "XXXL":
                return SizeCode.XXXL;
            default:
                return SizeCode.Unknown;
        }
    }

}

public enum SizeCode
{
    XXS = 1,
    XS = 2,
    S = 3,
    M = 4,
    L = 5,
    XL = 6,
    XXL = 7,
    XXXL = 8,
    Unknown = 9
}

И я сортирую это так:

units = units.OrderBy(x => (int)x.SizeCode).ToList();

Любые комментарии или что я могу улучшить?

Ответы [ 5 ]

3 голосов
/ 20 февраля 2012

Как насчет использования enum

public enum Size
    {
        Small = 1,
        Medium = 2,
        // etc 

    }

Затем вы можете преобразовать значение перечисления в классе Unit в int и отсортировать по целочисленному значению.

2 голосов
/ 20 февраля 2012

Хорошо, я считаю, что в вашей базе данных должен быть столбец OrderIndex и сортировка по этому столбцу.

грязный способ - иметь свой собственный класс с интерфейсом: IComparer или сделать то же самое, что делегат для сортировки.

Проверьте ICompararer в MSDN: http://msdn.microsoft.com/en-us/library/system.collections.icomparer.aspx

1 голос
/ 20 февраля 2012

Вы можете сделать именно то, что MSDN предлагает здесь :

// First, declare a few classes that implement the IComparer interface.
public class CompareShirtSize : IComparer<string>
{
    // Because the class implements IComparer, it must define a 
    // Compare method. The method returns a signed integer that indicates 
    // whether s1 > s2 (return is greater than 0), s1 < s2 (return is negative),
    // or s1 equals s2 (return value is 0). This Compare method compares strings. 
    public int Compare(string size1, string size2)
    {
        // Do size comarison here
        return ConvertSizeToInt(size1) - ConvertSizeToInt(size2);
    }

    private int ConvertSizeToInt(string size)
    {
      switch (size)
      {
        case "XXS":
            return 1;
        case "XS":
            return 2;
        case "S":
            return 3;
        case "M":
            return 4;
        case "L":
            return 5;
        default:
           // some error handling
       }
}


// The following method tests the Compare methods defined in the previous classes.
public static void OrderByIComparer()
{
    List<Unit> units;

     // Sort the elements of the array alphabetically.
    var sortedList = units.OrderBy(unit => unit.Size, new CompareShirtSize ());
}
0 голосов
/ 20 февраля 2012

Вам просто нужно использовать делегат сравнения. Во-первых, создайте функцию, которая просто присваивает число каждому размеру, а затем используйте его для сравнения:

(Я не уверен, что ваши размеры хранятся в виде строки как перечисления; но я бы рекомендовал хранить их как перечисление с порядковыми номерами в порядке увеличения или уменьшения размеров. Это поможет делегату сравнения быстрее и проще).

public class ShirtSizeCompare {
    private static int getIndex(Unit x) {
        if(x == Null) { return -1; }

        if(x.size == "S") {
            return 0;
        } else if(x.size == "M") {
            return 1;
        }

        ///...
    }            

    private static int CompareShirts(Unit x, Unit y) {
        int _x = getIndex(x);
        int _y = getIndex(y);

        if(_x < _y) {
            return -1;
        } else if(_x == _y) {
            return 0;
        } else {
            return 1;
        }
    }
}

Затем просто используйте делегат Comparison для сортировки списка:

List<Unit> unitList;
unitList.sort(CompareShirts);

Делегат сравнения в основном принимает в качестве входных данных две переменные x и y и возвращает:

<0 (if x < y)
>0 (if x > y)
0  (if x == y)

Проверьте эту страницу для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/w56d4y5z.aspx

0 голосов
/ 20 февраля 2012

Вы можете добавить Size свойство типа int в вашем классе Unit. Затем отсортируйте свой список, используя это свойство Size.

public class Unit1
{
    public Unit1(string name)
    {
        this.Name = name;

        switch (this.Name)
        {
            case "XXS":
                this.Size = 1;
                break;
            case "XS":
                this.Size = 2;
                break;
            case "S":
                this.Size = 3;
                break;
            case "M":
                this.Size = 4;
                break;
            case "L":
                this.Size = 5;
                break;
        }
    }

    public string Name { get; set; }

    public int Size { get; private set; }

    public int Value { get; set; }
}

private static void Main(string[] args)
{
    List<Unit1> list1 = new List<Unit1>();
    list1.Add(new Unit1("XS") { Value = 1 });
    list1.Add(new Unit1("M") { Value = 1 });
    list1.Add(new Unit1("S") { Value = 1 });
    list1.Add(new Unit1("L") { Value = 1 });

    var sortedList = list1.OrderBy(z => z.Size).ToList();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...