2015-02-21 5 views
0

Я пытаюсь написать метод под названием calculate, который определяет add или subtract номеров в зависимости от аргумента ключевого слова, переданного ему.Ruby - Уменьшить массив чисел в ruby ​​возвращает странный результат

Here're методы:

def add(*num) 
    num.inject(:+) 
end 

def subtract(*num) 
    num.reduce(:-) 
end 

def calculate(*num, **op) 
    return add(num) if op[:add] || op.empty? 
    return subtract(num) if op[:subtract] 
end 

puts calculate(1, 2, 3, add: true) 
puts calculate(1, 2, 3, subtract: true) 

Когда я запускаю эту функцию, я получаю этот результат:

1 
2 
3 

1 
2 
3 
+0

@sawa сделано ли это с использованием только восклицательный знак и извлечения последнего элемента? Извините, я новичок в Ruby. –

+1

Если вы следуете моим рекомендациям, то ваш метод будет просто 'def calculate * args, op; args.inject (case op; when: add then: +; when: subtract then: - end) end'. – sawa

+1

Или, если вы решите, что можете пойти с 'calculate (1, 2, 3,: +)', 'calculate (1, 2, 3, :-)', тогда это будет 'def calculate * args, op; args.inject (op) end'. – sawa

ответ

2

puts ваш друг:

def add(*num) 
    puts "in add, num = #{num}, num.size = #{num.size}" 
    num.inject(:+) 
end 

def calculate(*num, **op) 
    puts "num = #{num}, op = #{op}" 
    return add(num) if op[:add] || op.empty? 
end 

calculate(1, 2, 3, add: true) 
    # num = [1, 2, 3], op = {:add=>true} 
    # in add, num = [[1, 2, 3]], num.size = 1 
    #=> nil 

Зафиксируем calculate:

def calculate(*num, **op) 
    puts "num = #{num}, op = #{op}" 
    return add(*num) if op[:add] || op.empty? 
end 

calculate(1, 2, 3, add: true) 
    # num = [1, 2, 3], op = {:add=>true} 
    # in add, num = [1, 2, 3], num.size = 3 
    # => 6 
+0

Но можете ли вы сказать мне, почему в 'методе' метод вычисления, заменив 'add (num)' на 'add (* num)' решил? –

+0

Скажите 'a = [1,2,3]'. 'add' добавляет свои аргументы вместе, поэтому:' add (* a) => add (1,2,3) => 6'. С 'add (a)', 'add' имеет только один аргумент, массив' a'. Когда один или несколько массивов передаются в качестве аргументов 'add',' arr.inject (: +) 'использует [Array # +] (http://ruby-doc.org//core-2.2.0/Array.html # method-i-2B), а не [Fixnum # +] (http://ruby-doc.org//core-2.2.0/Fixnum.html#method-i-2B): 'add ([1,2 ], [3,4]) => [1, 2, 3, 4] ',' add ([1,2]) => [1, 2] '. Понял? –

0

Вы пишете:

return add(*num) if opt[:add] || opt.empty? 

Таким же образом изменить возвращение вычтите .. Часть тоже.

С вашим размещенным кодом num становится [[1,2,3]], и, таким образом, [[1,2,3]]. Inject (: +) возвращает получателю обратно. И вы называете puts on it, поэтому он выводится, как и вы.

+0

Хм, похоже, сейчас работает. Но не могли бы вы объяснить, почему передача '* num' работает и передача' num' не так, как я показал выше? –

+0

Я на Мобил, дай мне немного. –

+0

https://ideone.com/1rNLDu проверить это –