Вопрос

Я сталкиваюсь с чем -то, чего я не полностью понимаю.

У меня есть массив, элементы которых являются массивами.

Так что у меня есть две вложенные петли, во внутренней петле я заполняю свой внутренний массив, затем во внешней петле я заполняю внешний массив внутренним массивом.

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

Другие советы

Мне нравится подход Использование хэшей вместо многомерных массивов.

Как насчет этого:

def creat­e_matrix x, y, conte­nt = nil, &block
  rows = (0...x­).to_a
  cols = (0...y­).to_a
  indices = rows.­product cols
  matrix = {}
  indices.ea­ch { |inde­x| matri­x[index] = ( block­_given? ? yield­( index ) : conte­nt ) }
  matrix
end

Тогда делай:

matrix = create_matrix( 2, 2 ) { rand.to_s }

Вы получите хэш, к которому вы можете получить доступ к этому:

matrix[[0, 1]] #note the double brackets

Другой способ сделать это:

(1..4).map{rand}.each_slice(2).to_a
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top