Can this Ruby code be written more succinctly?
positions = Hash.new
import_profile.headings.each do |h|
positions[h.table_name + '.' + h.column_name] = h.position
end
Once this is done, the thing I'm interested i开发者_如何学JAVAn is positions
. This is pretty much exactly how I would write this kind of thing in PHP but I was attracted to Ruby for its map
and collect
functions. Is there maybe a one-line way to write this?
I think the most succinct would be something like this.
positions = Hash[*import_profile.headings.map do|h|
[ "#{h.table_name}.#{h.column_name}", h.position ]
end.flatten
]
But that's not terribly readable. I like your code better.
positions = Hash[ import_profile.headings.map do |h|
[ "#{h.table_name}.#{h.column_name}", h.position ]
end ]
or
positions = Hash[ *import_profile.headings.map do |h|
[ "#{h.table_name}.#{h.column_name}", h.position ]
end.flatten ]
The former only works in Ruby 1.8.7+, where Hash.[]
is allowed to receive an array of two-value arrays. The latter works in earlier versions, where Hash.[]
was only allowed to receive an even number of parameters.
If you are interested, this is how inject
based solution would look like. Not shorter, but a bit more FP-ish:
positions = import_profile.headings.inject({}) do |acc,h|
acc["#{h.table_name}.#{h.column_name}"] = h.position
acc
end
Hash[import_profile.headings.map { |h| ["#{h.table_name}.#{h.column_name}", h.position] }]
Another way of joining the words together is to use join
:
positions = Hash.new
import_profile.headings.each do |h|
positions[[h.table_name, h.column_name].join(".")] = h.position
end
精彩评论