какво връща инжектирането? и какво може да има в блок?

В кода по-долу Океанът представлява височините на подводните планини. 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