Відсортуйте список за алфавітом


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, я щойно почув припущення, що я міг би цим скористатися.

Відповіді:


154

Ви можете відсортувати список на місці, просто зателефонувавши List<T>.Sort:

list.Sort();

Для цього буде використано природне впорядкування елементів, що у вашому випадку прекрасно.

EDIT: Зверніть увагу, що у вашому коді вам знадобиться

_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>.
Джон Скіт,

24

Є два шляхи:

Без LINQ: yourList.Sort();

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

Більше інформації ви знайдете за адресою : http://www.dotnetperls.com/sort-string-array


@Dminox - Мій список виглядає так: IList <string> nD. Я спробував nD.Sort (), але там написано: Не вдається вирішити символ "Сортувати".
Маріко

1
@Mariko Sort()є членом List<T> не IList<T> . Ви можете розглянути можливість переходу на попередню IList<T>
версію

23

Інший спосіб

_details.Sort((s1, s2) => s1.CompareTo(s2)); 

10
Ця перевага має адаптацію до сортування будь-якого об’єкта за однією з його властивостей .
MGOwen

11

Ви повинні мати можливість використовувати OrderByв LINQ ...

var sortedItems = myList.OrderBy(s => s);

2
Примітка: це повертається IEnumerable<T>і не відбувається на місці сортування
абатищев

1

@goril - Я хотів би використовувати це, але я отримую повідомлення про помилку. Це те, що я додав до іншого коментаря. Сподіваюся, ви можете допомогти - Мій список виглядає так: IList <string> nD. Я спробував nD.Sort (), але там написано: Не вдається вирішити символ "Сортувати".
Маріко

1
@Mariko: ви використовуєте інтерфейс IList <T>, який не містить методу сортування. Змінна списку сортування <T> безпосередньо. Іншими словами, ви можете сортувати _detailsзі свого прикладу, але ніDetails
Олег Дудник
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.