Вызывает ли использование метода Ruby 'push' удаление значения из исходного массива?
Я нашел следующий код в качестве решения проблемы новичка Ruby, включающей рандомизацию. Я понимаю, что у Ruby есть метод shuffle
, однако цель моего вопроса заключается именно в push
.
def shuffle arr
shuf = []
while arr.length > 0
# Randomly pick one element of the array.
rand_index = rand(arr.length)
# Now go through each item in the array,
# putting them all into new_arr except for the # randomly chosen one, which goes into shuf.
curr_index = 0
new_arr = []
arr.each do |item|
if curr_index == rand_index
shuf.push item
else
new_arr.push item
end
curr_index = curr_index + 1
end
# Replace the original array with the new, # smaller array.
puts arr.inspect
arr = new_arr
end
shuf
end
shuffle_array = [1,2,3,4,5,6,7,8,9]
shuffle(shuffle_array)
Вывод в командной строке был следующим:
Rick:programs rickthomas$ ruby shuffleSolution.rb
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 8, 9]
[1, 2, 3, 4, 5, 8, 9]
[1, 2, 3, 4, 5, 9]
[1, 2, 3, 4, 9]
[1, 3, 4, 9]
[3, 4, 9]
[3, 9]
[3]
Rick:programs rickthomas$
Судя по строке while arr.length > 0
, похоже, что arr
убывает постепенно, что, как я предполагаю, связано с pushing
элементами из arr
в любой из двух других массивов. Чтобы проверить это предположение, я возился с следующий код:
array1 = [1,2,3,4,5,6,7,8]
array2 = []
array3 = []
array1.each do |x|
random_num = rand(2)
if random_num == 1
array2.push x
else
array3.push x
end
puts array1.inspect
end
Я ожидал, что array1 уменьшится аналогично методу shuffle
выше, но вместо этого я получил следующее:
Rick:programs rickthomas$ ruby socratesWork.rb
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
Rick:programs rickthomas$
Почему push
удаляет элементы массива в первом фрагменте, но не во втором? Я просто где-то упустил синтаксическую ошибку, или я неправильно понял что-то более фундаментальное о push
?
Я уже искал Stack Overflow для ответа на этот вопрос, и не смог найти аналогичный вопрос, опубликованный еще. Я тоже проверил ruby-doc.org, но он говорил только о добавлении к массиву, а не о перемещении (?) элементы из одного массива в другой.
3 ответа:
Ну, вы толкаете все элементы , кроме одного с соответствующим индексом в
new_arr
. Его размер уменьшается на единицу в каждой итерации.
Похоже, что вы заменяете свой массив на меньший массив на каждой итерации.
# Replace the original array with the new, # smaller array. puts arr.inspect arr = new_arr
В первом фрагменте внутренний цикл разбивает исходный массив
arr
на 2 части:Таким образом, в каждом внешнем цикле
- элемент, который соответствует случайному индексу, и он помещается в массив
shuf
- те элементы, которые не соответствуют случайному индексу, они были помещены в
new_arr
, который инициализируется как пустой массив в каждом внешнем цикле.shuf
получает еще один элемент, аnew_arr
получает все элементы вarr
, кроме случайно выбранного. То магия выходит в последней строке внешнего цикла, гдеnew_arr
присваиваетсяarr
. Таким образом, каждый циклarr
становится на один элемент меньше. Это не магия или побочный эффектArray#push
.