Я знаю, что я могу выбрать случайный элемент из массива с помощью метода образца, но это оставляет возможность выбора элемента более одного раза. Сначала я мог сначала перетасовать массив, а затем перейти от первого к последнему элементу по порядку, но я понимаю, что это интенсивный процесс памяти, и я ищу менее интенсивный метод, если это возможно!Выбор случайного элемента из массива в Ruby ONCE ONLY
ответ
Шаркая массив не большой объем памяти. Ruby имеет стандартную реализацию тасования по умолчанию, она называется Array.shuffle!
. Глядя на исходный код для этого вы можете увидеть (это C):
rb_ary_shuffle_bang(ary)
VALUE ary;
{
long i = RARRAY(ary)->len;
rb_ary_modify(ary);
while (i) {
long j = rb_genrand_real()*i;
VALUE tmp = RARRAY(ary)->ptr[--i];
RARRAY(ary)->ptr[i] = RARRAY(ary)->ptr[j];
RARRAY(ary)->ptr[j] = tmp;
}
return ary;
}
Эта реализация следует классический Fisher-Yates algorithm.
Итак:
- Перемешать массив на месте с помощью
shuffle!
. Сложность времени -O(n)
, дополнительной памяти не требуется. - Итерации над массивом. Сложность времени -
O(n)
, дополнительная память не требуется (только целое число для хранения текущего индекса).
В целом у вас есть то, что вам нужно без дополнительной памяти и временной сложности O(n)
.
Вы должны отслеживать те элементы, которые вы уже выбрали; что вы собираетесь делать, поместите их в свой собственный массив?
Shuffle and iterate. Это не занимает больше памяти, чем отслеживание уже выбранных элементов.
Если элементы массива действительно очень большой, то можно попробовать просто перетасовать список индексов и перебирать, что:
a = %w{a b c d e f g h}
[*0...a.size].shuffle.each do |index|
puts a[index]
end
sample
принимает аргумент:
[*(1..10)].sample(5) #=>[3, 4, 1, 8, 9]
Ни один элемент не будет выбран в два раза.
Не мой вопрос, но это то, чего я не знал, и может предвидеть, что буду полезным в будущем. +1 – KChaloux
- 1. Выбор случайного элемента из массива
- 2. Выбор случайного элемента из массива iOS
- 3. Выбор случайного элемента из массива с исключениями
- 4. Выбор случайного элемента из многомерного массива
- 5. Выбор случайного элемента из набора
- 6. Выбор случайного элемента из объекта
- 7. Выбор случайного цвета из массива
- 8. Ruby 1.9 - Выбор элемента из 2D массива
- 9. Выбор случайного из массива ascctive
- 10. Выбор случайного элемента из массива строк в java
- 11. Выбор случайного элемента коллекции
- 12. window.onresize call only once
- 13. Animate Chart.JS Only Once
- 14. ISupportIncrementalLoading only fire once
- 15. Сделать Link_to_remote Clickable Only Once
- 16. Получение случайного элемента из массива ruby (ваше решение)?
- 17. Clone InsertAfter inserting only once
- 18. Эффективный выбор случайного элемента из цепочки хэшей?
- 19. Выбор случайного элемента из помеченной библиотеки
- 20. Racket - выбор случайного элемента из списка
- 21. Выбор случайного элемента из списка (Bukkit)
- 22. Выбор случайного элемента набора мощности
- 23. Ajax call only update once
- 24. Клон и insertAfter only once
- 25. Инициализировать Async Only Once Pattern
- 26. count checkbox class only once
- 27. Выбор случайного изображения из массива изображений
- 28. Выбор и использование случайного класса из массива
- 29. выбор случайного слова из массива слов
- 30. Выбор случайного массива из списка массивов
Почему вы говорите, что перетасовка массива интенсивна в памяти? Самые наивные реализации перетасовывают массив на месте. – aromero
Документы заявляют, что '# sample' не будет выбирать элементы более одного раза. '[1, 2] .sample (3)' возвращает '[1, 2]' или '[2, 1]'. – Nick