开发者

Can this Ruby code be written more succinctly?

开发者 https://www.devze.com 2023-02-03 18:08 出处:网络
positions = Hash.new import_profile.headings.each do |h| positions[h.table_name + \'.\' + h.column_name] = h.position
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
0

精彩评论

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