0

我正在尝试评估数组中的每个位置,如果它在某个范围内,则为该位置分配一个新值。这是我的方法代码和方法调用:

def array_eval array
    array.each do |x|
        if x.to_i <= 10
            array[x] = 1
        else
            array[x] = 2
        end
    end
end

array_eval temp_array
puts temp_array

这是我从终端输出的错误:

carwashalgorithm.rb:109:in `[]=': no implicit conversion from nil to integer (TypeError)

from carwashalgorithm.rb:109:in `block in array_eval'
from carwashalgorithm.rb:107:in `each'
from carwashalgorithm.rb:107:in `array_eval'
from carwashalgorithm.rb:117:in `<main>'

我可以使用控制流来做到这一点,但我知道有一种更简单的方法可以使用块来评估所有这些值。这就是我要对上述内容做的事情。任何和所有的帮助表示赞赏。

4

3 回答 3

2

您的each循环为每个元素调用给定块,并传递该元素:

array.each do |x| # <- x is a reference to an element
  # ...
end

Array#[]=在您使用该元素调用的循环内:

  array[x] = 1    # <- the same x

这不起作用(它会引发TypeError),您必须传递元素的index

您可以使用Array#each_index- 它传递索引而不是元素本身:

def array_eval(array)
  array.each_index do |x|
    if array[x].to_i <= 10
      array[x] = 1
    else
      array[x] = 2
    end
  end
end

或者Array#map!- 它用块返回的值替换元素:

def array_eval(array)
  array.map! do |item|
    if item <= 10
      1
    else
      2
    end
  end
end

以上可以写成单行(见jethroo的回答):

def array_eval(array)
  array.map! { |item| item <= 10 ? 1 : 2 }
end
于 2013-10-22T21:32:49.627 回答
1

这可以在 ruby​​ 的一行中完成:

array.map{|x| x.to_i <= 10 ? 1 : 2}

1.9.3-p194 :003 > a = [*0..20]
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 
1.9.3-p194 :004 > a.map{|x| x <= 10 ? 1 : 2}
=> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] 
于 2013-10-22T20:27:22.613 回答
1

也许错误是因为 temp_array 尚未实例化(我没有在您的代码示例中看到 temp_array 的创建)。但是,如果问题类似于上面的@jethroo 状态,并且您的数组中有一个 nil 值,您可以在评估 .to_i 之前对每个元素添加一个检查 nil :

array.map{|x| 
  if x.nil?
    puts 'element is nil, moving on...'
  else
    x.to_i <= 10 ? 1 : 2
}
于 2013-10-22T20:55:10.563 回答