开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜