Случайный порядок IEnumerable - PullRequest
       32

Случайный порядок IEnumerable

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

У меня есть коллекция IEnumerable следующим образом

var result1 = GetResult1() // Returns 2,4,5,6

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

var result2 = GetResult2(result1) // Returns 2,4,5,6 in a random order.
// An example output would be 4,6,2,5 in the resultant collection.

Я сделал это следующими способами:

var result1 = GetResult1();
var random = new Random();
var result2 = result1.OrderBy(order=>random.Next());

Однако проблема в том, что, если я получаю доступ к result2, элементы в result2 снова перетасовываются, т. Е. Если я дважды выводю результаты result2 на консоль, элементы снова подвергаются жонглированию.

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

Ответы [ 3 ]

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

Вы ищете алгоритм перемешивания .

См. Следующие потоки SO, чтобы обеспечить хороший метод расширений для выполнения работы:

Использует Random иЗакажите хороший алгоритм тасования?

Метод расширения на IEnumerable, необходимый для тасования


Чтобы ответить на ваш вопрос «почему это снова тасуется?», это из-за того, как OrderBy работает (ленивое выполнение).Вы можете попробовать:

var result2 = result1.OrderBy(order=>random.Next()).ToList();
1 голос
/ 20 февраля 2012

Я вижу, вам требуется ленивая оценка результатов, в этом случае вы можете сделать следующее:

var randomNumbers = result1.Select(r => random.Next()).ToArray();
var orderedResult = result1.Zip(randomNumbers, (r, o) => new { Result = r, Order = o })
    .OrderBy(o => o.Order)
    .Select(o => o.Result);

Вызвав ToArray() для случайных чисел, они не изменятся.Когда вы, наконец, желаете элементы в result, вы можете застегнуть элементы случайными числами, OrderBy случайным числом и Select результатом.

Пока элементы в result располагаются в одном и том же порядке, результат в orderedResult должен быть одинаковым каждый раз.

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

Вы можете использовать ToList() так:

var result2 = result1.OrderBy(order=>random.Next()).ToList();
...