Сортировать список по алфавиту

83

У меня следующий класс:

class Detail
{
    public Detail()
    {
        _details = new List<string>();
    }
    public IList<string> Details { get { return _details; } }
    private readonly List<string> _details;
}

В настоящее время я сортирую класс случайным образом, используя следующее:

void ShuffleGenericList<T>(IList<T> list)
{
    //generate a Random instance
    var rnd = new Random();
    //get the count of items in the list
    var i = list.Count();
    //do we have a reference type or a value type
    T val = default(T);

    //we will loop through the list backwards
    while (i >= 1)
    {
        //decrement our counter
        i--;
        //grab the next random item from the list
        var nextIndex = rnd.Next(i, list.Count());
        val = list[nextIndex];
        //start swapping values
        list[nextIndex] = list[i];
        list[i] = val;
    }
}

Я хотел бы отсортировать содержимое деталей в алфавитном порядке.

Так, например, если содержимое выглядит так:

[0] a
[1] d
[2] b

Я хочу иметь возможность запустить этот метод и отсортировать их по:

[0] a
[1] b
[2] d

Кто-нибудь знает простой способ это сделать? Обратите внимание, что списки обычно содержат менее десяти записей. Могу ли я сделать это с помощью LINQ? Извините, но я не очень знаком с LINQ. Я только что услышал предложение, что я могу это использовать.

Марико
источник

Ответы:

155

Вы можете отсортировать список на месте, просто позвонив List<T>.Sort:

list.Sort();

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

РЕДАКТИРОВАТЬ: обратите внимание, что в вашем коде вам понадобится

_details.Sort();

поскольку Sortметод определен только в List<T>, а не IList<T>. Если вам нужно отсортировать его извне, где у вас нет доступа к нему как List<T>(вы не должны приводить его, поскольку List<T>часть является деталью реализации), вам нужно проделать немного больше работы.

Я не знаю каких-либо IList<T>сортировок на месте в .NET, что немного странно, когда я думаю об этом. IList<T>предоставляет все необходимое, поэтому его можно было бы написать как метод расширения. Есть много реализаций быстрой сортировки, если вы хотите использовать одну из них.

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

public void Sort<T>(IList<T> list)
{
    List<T> tmp = new List<T>(list);
    tmp.Sort();
    for (int i = 0; i < tmp.Count; i++)
    {
        list[i] = tmp[i];
    }
}

Другими словами, скопируйте, отсортируйте на месте, а затем скопируйте отсортированный список обратно.


Вы можете использовать LINQ для создания нового списка, который содержит исходные значения, но отсортирован:

var sortedList = list.OrderBy(x => x).ToList();

Это зависит от того, какое поведение вы хотите. Обратите внимание, что ваш метод перемешивания не совсем идеален:

  • Создание нового Randomвнутри метода сталкивается с некоторыми проблемами, показанными здесь.
  • Вы можете объявить valвнутри цикла - вы не используете это значение по умолчанию
  • Более идиоматично использовать Countсвойство, когда вы знаете , что работаете сIList<T>
  • На мой взгляд, forцикл проще для понимания, чем обход списка назад с помощью whileцикла

Есть и другие реализации перетасовки с помощью Fisher-Yates в Stack Overflow - ищите, и вы найдете один довольно быстро.

Джон Скит
источник
Итак, если бы я хотел отсортировать список, который вы создали выше, мне просто нужно было бы сказать: sortedList.Sort?
Марико
Я пробовал Сортировку, но не могу заставить ее работать. Мой список выглядит так: IList <string> nD. Я пробовал nD.Sort (), но он говорит: не удается разрешить символ «Сортировка».
Марико
@Mariko: Используйте _details.Sort()вместо этого - так _detailsдекларируется как List<string>вместо IList<string>. Sortтолько объявляется List<T>, нет IList<T>.
Джон Скит,
25

Есть два способа:

Без LINQ: yourList.Sort();

С LINQ: yourList.OrderBy(x => x).ToList()

Дополнительную информацию можно найти по адресу : https://www.dotnetperls.com/sort

Дамиокс
источник
@Dminox - Мой список выглядит так: IList <string> nD. Я пробовал nD.Sort (), но он говорит: не удается разрешить символ «Сортировка».
Марико
1
@Mariko Sort()является участником List<T> not IList<T> . Вы можете подумать о переходе на первый IList<T>
вариант
24

По-другому

_details.Sort((s1, s2) => s1.CompareTo(s2)); 
Лашра
источник
10
У этого есть преимущество адаптации к сортировке любого объекта по одному из его свойств .
MGOwen
11

Вы должны иметь возможность использовать OrderByв LINQ ...

var sortedItems = myList.OrderBy(s => s);
Квинтин Робинсон
источник
2
Примечание: это возвращается, IEnumerable<T>а не сортировка по месту
абатищев 06
1

Что не так List<T>.Sort()?

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.sort#overloads

Олег Дудник
источник
@goril - я хотел бы использовать это, но получаю ошибку. Это то, что я добавил к другому комментарию. Надеюсь, вы можете помочь - мой список выглядит так: IList <string> nD. Я пробовал nD.Sort (), но он говорит: не удается разрешить символ «Сортировка».
Марико
1
@Mariko: вы используете интерфейс IList <T>, который не содержит метода Sort. Сортировка переменных List <T> напрямую. Другими словами, вы можете сортировать _detailsпо вашему примеру, но не можетеDetails
Олег Дудник 06