Я сталкиваюсь с чем -то, чего я не полностью понимаю.
У меня есть массив, элементы которых являются массивами.
Так что у меня есть две вложенные петли, во внутренней петле я заполняю свой внутренний массив, затем во внешней петле я заполняю внешний массив внутренним массивом.
arr=[]
mat=[]
for m in (0..1)
for k in (0..1)
arr[k]=rand.to_s
end
mat[m]=arr
end
В конце моя матрица заполнена двумя массивами; Каждый массив содержит значения, рассчитанные в последней итерации. Если я хочу, чтобы первый элемент в матрице содержал первый вычисленный массив, я должен повторно реализовать объект ARR в каждом цикле. Таким образом, кажется, что назначение выполняется ссылкой до тех пор, пока объект ARR не будет «очищен». Если я добавлю
mat[m]=arr
arr=[]
Все работы, как и ожидалось: MAT [0] будет содержать массив, рассчиненный в первом цикле, и Mat [1] будет содержать массив, вычисленный во втором цикле.
Это по дизайну или это нежелательный побочный эффект? Это происходит только в том случае, если я назначаю массивы в качестве элементов массива. Если заполнить массив простыми строковыми переменными в цикле, все идет так, как и ожидалось.
Я знаю, что это хорошая практика программирования, чтобы избежать повторного использования объектов, но это поведение в любом случае странное.
Решение
Ваша проблема заключается в том, что содержимое переменной ARR перезаписывается каждой итерацией: arr[k] перезаписывает все, что уже там есть. Вместо этого переменная ARR должна быть локальной для блока:
mat = []
2.times do # avoid for... use iterators instead
row = []
2.times do
row << rand.to_s
end
mat << row
end