I'm trying to evaluate each position in an array and assign a new value to that position if it falls within a certain range. Here is my method code and method call:
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
And here is my output error from the terminal:
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>'
I can do this with control flow, but I know there is an easier way to evaluate all of these values using a block. This is what I'm trying to do with the above. Any and all help is appreciated.
Your each
loop calls the given block for each element, passing that element:
array.each do |x| # <- x is a reference to an element
# ...
end
Inside the loop you call Array#[]=
with that element:
array[x] = 1 # <- the same x
This doesn't work (it raises the TypeError
), you have to pass the element's index.
You could use Array#each_index
- it passes the index instead of the element itself:
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
Or Array#map!
- it replaces the element with the value returned by the block:
def array_eval(array)
array.map! do |item|
if item <= 10
1
else
2
end
end
end
The above can be written as a one-liner (see jethroo's answer):
def array_eval(array)
array.map! { |item| item <= 10 ? 1 : 2 }
end