Случайный массив с использованием LINQ и С#
Я читал статью в журнале MSDN об использовании класса Enumerable в LINQ для генерации случайного массива. В статье используется VB.NET, и я не сразу понял, что эквивалентно в С#:
Dim rnd As New System.Random()
Dim numbers = Enumerable.Range(1, 100). _
OrderBy(Function() rnd.Next)
Ответы
Ответ 1
Разработчик Fusion VB.Net to С# converter говорит, что эквивалентный код С#:
System.Random rnd = new System.Random();
IEnumerable<int> numbers = Enumerable.Range(1, 100).OrderBy(r => rnd.Next());
Для справки в будущем они также имеют С# в VB.Net-конвертер. Для этого доступны несколько других инструментов.
Ответ 2
Random rnd = new Random();
IEnumerable<int> numbers = Enumerable.Range(1, 100).OrderBy(r => rnd.Next());
Ответ 3
Первоначально я думал, что это будет плохой идеей, так как алгоритму сортировки нужно будет делать несколько сравнений для чисел, и он получит другой сортировочный ключ для того же номера каждый раз, когда он называет лямбда для этого числа. Однако похоже, что он называет его только один раз для каждого элемента в списке и сохраняет это значение для последующего использования. Этот код демонстрирует это:
int timesCalled = 0;
Random rnd = new Random();
List<int> numbers = Enumerable.Range(1, 100).OrderBy(r =>
{
timesCalled++;
return rnd.Next();
}
).ToList();
Assert.AreEqual(timesCalled, 100);
Ответ 4
Как насчет чего-то гораздо более легкого...
Enumerable.Range(1, 100).OrderBy(c=> Guid.NewGuid().ToString())
Ответ 5
Лучшее, что я могу сделать с моей головы без доступа к Visual Studio (скрещивает пальцы):
System.Random rnd = New System.Random();
IEnumerable<int> numbers = Enumerable.Range(1, 100).OrderBy(rnd => rnd.Next);
Ответ 6
Используя C5 Generic Collection Library, вы можете просто использовать встроенный метод Shuffle()
:
IList<int> numbers = new ArrayList<int>(Enumerable.Range(1,100));
numbers.Shuffle();