这个Ruby代码可以更简洁地编写吗?

时间:2011-01-12 21:35:00

标签: ruby

positions = Hash.new
import_profile.headings.each do |h|
  positions[h.table_name + '.' + h.column_name] = h.position
end

一旦完成,我感兴趣的是positions。这几乎就是我在PHP中编写这种东西的方式,但我对Ruby的mapcollect函数感兴趣。可能有一种单行方式来写这个吗?

5 个答案:

答案 0 :(得分:4)

我认为最简单的简洁就是这样的。

positions = Hash[*import_profile.headings.map do|h|
    [ "#{h.table_name}.#{h.column_name}", h.position ]
  end.flatten
]

但这并不是非常可读。我更喜欢你的代码。

答案 1 :(得分:2)

positions = Hash[ import_profile.headings.map do |h|
  [ "#{h.table_name}.#{h.column_name}", h.position ]
end ]

positions = Hash[ *import_profile.headings.map do |h|
  [ "#{h.table_name}.#{h.column_name}", h.position ]
end.flatten ]

前者仅适用于Ruby 1.8.7+,其中Hash.[]允许接收双值数组的数组。后者适用于早期版本,其中Hash.[]仅允许接收偶数个参数。

答案 2 :(得分:2)

如果您有兴趣,这就是基于inject的解决方案的样子。不短,但更多FP-ish:

positions = import_profile.headings.inject({}) do |acc,h|
  acc["#{h.table_name}.#{h.column_name}"] = h.position
  acc
end

答案 3 :(得分:1)

Hash[import_profile.headings.map { |h| ["#{h.table_name}.#{h.column_name}", h.position] }]

答案 4 :(得分:0)

将单词组合在一起的另一种方法是使用join

positions = Hash.new
import_profile.headings.each do |h|
  positions[[h.table_name, h.column_name].join(".")] = h.position
end