How do I get the following to happen: I want to change the value of an array element which is being referenced between pipe characters in a .each
loop.
Map is probably the best way, but you can change the string in-place too.
> a = "hello"
> puts a
=> hello
> a.replace("hi")
> puts a
=> hi
changes the internal value of the string. For example, your code could become :
x = %w(hello there world)
x.each { |e| if (e == "hello"); e.replace("hi") end; }
but this is much nicer :
x = %w(hello there world)
x.map! { |e| e == "hello" ? "hi" : e }
x = %w(hello there world)
x[index] = "hi" if index = x.index("hello")
x[index] = "hi" if index
or
x = %w(hello there world)
index = x.index("hello") and x[index] = "hi"
But one notice: it will replace only first match. Otherwise use map!
as @SirDarlus suggested
Also you can use each_with_index
x.each_with_index do |element, index|
x[index] = "hi" if element == "hello" # or x[index].replace("hi") if element == "hello"
end
But I still prefer using map!
:)
You can get the result you want using collect!
or map!
to modify the array in-place:
x = %w(hello there world)
x.collect! { |element|
(element == "hello") ? "hi" : element
}
puts x
At each iteration, the element is replaced into the array by the value returned by the block.
How about simply:
x = %w(hello there world).map! { |e| e == "hello" ? "hi" : e }
This is a way has less lines of code:
x = %w(hello there world)
x = x.join(",").gsub("hello","hi").split(",")
puts x
The each
method never changes the object it works on.
You should use map!
method instead:
x = %w(hello there world)
x.map! { |element|
if(element == "hello")
"hi" # change "hello" to "hi"
else
element
end
}
puts x # output: [hi there world]