Inplace enumeration
I am using ruby 1.8.7 and ruby on rails 3.x . I have many lines like this
lines = lines.map {|e| e.strip}
lines = lines.map {|e| e.upcase}
lines = lines.map {|e| sanitize_element(e)}
Rather than assigning new values to lines every time is there a better way to handle this. I know I can do
lines = lines.map {|e| sanitize_element(e.strip.upc开发者_如何学Case) }
but that is not the main point of this question. The main thing is to find if there is a way to handle the above case without assigning value to lines every time.
Basically I am looking for a solution as elegant as this, but I know there isn't a map!
in Enumerable.
lines.map! {|e| e.strip}
Just making sure that I am not missing out on a ruby feature.
Yes, by using Array#map!
:
lines.map! { |e| e.strip }
lines.map! { |e| e.upcase}
# ...
Often, an immutable method like map
is paired with a dangerous one like map!
, which causes the receiver to be modified. I recommend against using these, since half the point of nice, functional-style enumerable programming is to get the benefits of immutability (referential transparency, etc.). But if you're going to reassign on each enumeration, you might as well use map!
.
If I understand your question correctly, you could write
lines = lines.map {|e| e.strip}.map {|e| e.upcase}.map {|e| sanitize_element(e)}
in a fluent fashion. Is this what you meant?
In case if sanitize_element!
exists you can try this way:
lines.map! do |e|
e.strip
e.upcase
e.sanitize_element
end
I think it looks more clear.
For interest, note that you could leave the array alone and concentrate on modifying the strings themselves. Like this:
lines.each do |e|
e.strip!
e.upcase!
e.replace(e.sanitize_element)
end
In a quick benchmark on random data this looked like it ran in about 2/3rds the time of the multiple-map!
version, although obviously you'd want to verify this on your actual data and operations.
精彩评论