что возвращает инъекция? а что может быть в блоке?

В приведенном ниже коде океан представляет собой высоту подводных гор. atlantis — это набор координат различных мест. Я хочу суммировать высоты гор, на которые ссылается Атлантида.

require 'matrix'    
Ocean=Matrix[ [3,1,4,4,6,2,8,12,8,2],
        [6,2,4,13,25,21,11,22,9,3,],
        [6,20,27,34,22,14,12,11,2,5],
        [6,28,17,23,31,18,11,9,18,12],
        [9,18,11,13,8,9,10,14,24,11],
        [3,9,7,16,9,12,28,24,29,21],
        [5,8,4,7,17,14,19,30,33,4],
        [7,17,23,9,5,9,22,21,12,21,],
        [7,14,25,22,16,10,19,15,12,11],
        [5,16,7,3,6,3,9,8,1,5] ]

atlantis=[[2,3],[3,4]]




puts atlantis.inject {|sum, n| sum + Ocean[n(0),n(1)]}

Поскольку atlantis представляет собой массив массивов, n(0) должно ссылаться на первый элемент, 2, первого массива [2,3] при первом внедрении блока. Но ошибка, которую я получаю

t1.rb:15:in block in <main>': undefined methodn' для main:Object (NoMethodError) из t1.rb:15:in each' from t1.rb:15:ininject' из t1.rb:15:in `'

Кажется, это указывает на то, что он даже не знает, что такое «n». Что мне не хватает? И что именно n получает/обозначает в этом случае?


person user918069    schedule 30.07.2012    source источник
comment
Используйте квадратные скобки для ссылки на элемент массива [], а не круглые скобки, например. Ocean[n[0], n[1]].   -  person maerics    schedule 31.07.2012
comment
добавить заданное начальное значение сворачивания: inject(0)   -  person tokland    schedule 31.07.2012


Ответы (1)


Из документации Ruby для Enumerable#inject(...), эта функция возвращает результат многократного применения данного бинарного оператора к начальному значению и каждому последующему значению. Таким образом, возвращаемое значение должно быть объектом типа, возвращаемого блочной процедурой (или символом). В вашем случае блок в конечном итоге использует оператор + с числовыми аргументами, поэтому возвращаемое значение должно быть числовым.

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

atlantis.inject(0) { |sum,n| sum + Ocean[n[0],n[1]] } # => 65

Таким образом, ваша последовательность вызовов будет выглядеть примерно так:

# sum = seed = 0 (from .inject(0))
# sum = sum + Ocean[atlantis[0][0], atlantis[0][1]] = 34
# sum = sum + Ocean[atlantis[1][0], atlantis[1][1]] = 34 + 31
# sum = 65
person maerics    schedule 30.07.2012