Каков наилучший способ случайной реорганизации списка элементов в C #? - PullRequest
6 голосов
/ 06 января 2009

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

Ответы [ 7 ]

12 голосов
/ 06 января 2009

Как насчет алгоритма Кнута-Фишера-Йейтса ?

for (int i = cards.Length - 1; i > 0; i--)
{
    int n = rand.Next(i + 1);
    Swap(ref cards[i], ref cards[n]);
}

Код взят из Код ужаса . Это также рекомендуемое чтение о том, как люди часто делают это неправильно.

6 голосов
/ 06 января 2009

Проверьте этот крутой способ Linq сделать это:

public class Employee
{
    public int Id
    {
        get;
        set;
    }
    public string Name
    {
        get;
        set;
    }
}

Заполнить список:

    List<Employee> list = new List<Employee>();

    list.Add(new Employee { Id = 1, Name = "Davolio Nancy" });
    list.Add(new Employee { Id = 2, Name = "Fuller Andrew" });
    list.Add(new Employee { Id = 3, Name = "Leverling Janet" });
    list.Add(new Employee { Id = 4, Name = "Peacock Margaret" });
    list.Add(new Employee { Id = 5, Name = "Buchanan Steven" });
    list.Add(new Employee { Id = 6, Name = "Suyama Michael" });
    list.Add(new Employee { Id = 7, Name = "King Robert" });
    list.Add(new Employee { Id = 8, Name = "Callahan Laura" });
    list.Add(new Employee { Id = 9, Name = "Dodsworth Anne" });

Затем сортировать:

    list = list.OrderBy(emp => Guid.NewGuid()).ToList();

Credit

2 голосов
/ 06 января 2009

Позвольте мне направить вас к одному НЕПРАВИЛЬНОМУ способу сделать это, и способ, который я признаю, я использовал прежде, и никогда не видел ошибки этого до этого сообщения в блоге:

http://www.codinghorror.com/blog/archives/001015.html

2 голосов
/ 06 января 2009

Вы можете использовать алгоритм Фишера-Йейтса , который работает в линейном времени.

1 голос
/ 06 января 2009

Мое любимое решение для перетасовки - использовать N * log N sort и передавать ему предикат sort, который возвращает случайный результат. Он имеет приятную функцию, которую можно сделать с минимумом нового кода, используя строительные блоки, которые большинству языков пригодятся даже в самых полосатых версиях.

0 голосов
/ 06 января 2009

Попробуйте этот код здесь

Используется IComparer.Compare

Будет хорошей практикой, если вы выполняете функцию, используя generics

0 голосов
/ 06 января 2009

Я бы создал новый Список и заполнил его элементами, которые были выбраны случайным образом и удалены из исходного Списка.

...