Ruby неопределенный метод '**' - PullRequest
1 голос
/ 19 февраля 2020

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

def foo(a)

    a.each { |x| puts x ** 3 }

    a.each_slice(3) { |x| puts x }
    a.select do |x|

        if x%5 == 0
            puts x
        end
    end

    a.map { |x| x ** 3 }
    aa.inject(0) { |x, y| x * y }

end

a = Array.new(50)
a.each { |x| x = rand(10..100) }

foo(a)

Я получаю эту ошибку:

Traceback (most recent call last):
        3: from task2.rb:21:in `<main>'
        2: from task2.rb:3:in `foo'
        1: from task2.rb:3:in `each'
task2.rb:3:in `block in foo': undefined method `**' for nil:NilClass (NoMethodError)

Ответы [ 4 ]

2 голосов
/ 19 февраля 2020

Эта строка:

a.each { |x| x = rand(10..100) }

не делает то, что вы думаете, что делает. Каждый не меняет исходный массив. Если вы хотите изменить исходные значения, вам нужна карта!

irb(main):025:0> a = Array.new(50)
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
irb(main):026:0> a.each { |x| x = rand(10..100) }
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
irb(main):027:0> a
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
irb(main):028:0> a.map { |x| x = rand(10..100) }
=> [67, 34, 96, 50, 52, 68, 14, 88, 67, 19, 83, 40, 35, 98, 88, 98, 39, 73, 41, 60, 25, 47, 33, 73, 20, 41, 32, 19, 65, 67, 47, 14, 11, 67, 32, 32, 13, 36, 23, 100, 14, 10, 73, 20, 59, 94, 54, 25, 57, 28]
irb(main):029:0>
a
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]

 a.map! { |x| x = rand(10..100) }
=> [97, 83, 52, 54, 22, 54, 39, 32, 42, 70, 84, 15, 69, 32, 28, 40, 50, 98, 66, 79, 25, 37, 97, 28, 30, 11, 98, 57, 73, 77, 99, 75, 72, 40, 67, 62, 87, 41, 58, 10, 88, 24, 98, 10, 31, 94, 53, 43, 98, 17]
irb(main):032:0> a
=> [97, 83, 52, 54, 22, 54, 39, 32, 42, 70, 84, 15, 69, 32, 28, 40, 50, 98, 66, 79, 25, 37, 97, 28, 30, 11, 98, 57, 73, 77, 99, 75, 72, 40, 67, 62, 87, 41, 58, 10, 88, 24, 98, 10, 31, 94, 53, 43, 98, 17]
irb(main):033:0>

Также предпочтительным способом сделать это является диапазон IMO.

2 голосов
/ 19 февраля 2020

#each - это простая итерация, она не изменяет массив. Вместо:

a = Array.new(50)
a.each { |x| x = rand(10..100) }

вы можете просто сделать это:

a = Array.new(50) { rand(10..100) }
0 голосов
/ 20 февраля 2020

Вы должны использовать метод Ruby p, чтобы помочь вам отладить вещи. (p x является ярлыком puts x.inspect.)

Поэтому попробуйте запустить следующую программу:

a = Array.new(50)
a.each { |x| x = rand(10..100) }
p a

Из результатов этой программы вы можете видеть, что ваш массив состоит только из 50 ноль. Итак, ваш настоящий вопрос: как правильно инициализировать массив? Аргумент x вашего блока - это не какая-то ссылка на ячейку в массиве, это просто копия значения, которое содержалось в массиве, поэтому запись в x ничего не делает для массива.

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

a = Array.new(50) { rand(10..100) }

Вы также можете написать это так:

a = 50.times.map { rand(10..100) }

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

a = []
50.times { a << rand(10..100) }

Вы также можете использовать метод []=, который является наиболее общим способом записи в массив:

a = []
50.times { |i| a[i] = rand(10..100) }

Стоит знать о каждом из этих различных способов создания массива.

0 голосов
/ 19 февраля 2020

Вы не модифицируете свой массив из 50 нулевых значений. Вместо этого попробуйте map!.

a.map! { |x| x = rand(10..100) }

Не совсем точно, что должен делать остальной код, но, скорее всего, это так.

def foo(a)
  a.each { |x| puts x ** 3 }
  a.each_slice(3) { |x| puts x }
  a.each do |x| # not sure why you wanted select, does not make sense here
    if x % 5 == 0
      puts x
    end
  end

  a.map { |x| x ** 3 }
   .inject(0) { |x, y| x * y }
end

array = Array.new(50)
array.map! { |x| x = rand(10..100) }

foo(array)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...