2011-01-12 112 views
1
positions = Hash.new 
import_profile.headings.each do |h| 
    positions[h.table_name + '.' + h.column_name] = h.position 
end 

一旦完成,我感兴趣的事情是positions。这几乎就是我如何用PHP编写这种类型的东西,但我被Ruby的mapcollect函数吸引。有没有可能以单行的方式来写这个?这个Ruby代码可以写得更简洁吗?

回答

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

我觉得最简单简洁会是这样的。

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

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

+1

你缺少周围的表达方括号中的地图。如果你打算画出结果,你也错过了对“扁平化”的调用。这段代码甚至没有通过语法检查。 – Phrogz 2011-01-12 21:42:29

+0

你说得对。我以为我不需要使用摔跤运算符拼合。当我从另一台机器复制时,我也忘了添加方括号。 – AboutRuby 2011-01-12 22:14:26

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 ] 

前者只能在红宝石1.8.7+,其中Hash.[]被允许接收二值数组的数组。后者适用于早期版本,其中Hash.[]仅允许接收偶数个参数。

2

如果您有兴趣,这是基于inject的解决方案。为不短,但多一点FP-ISH:

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

加入单词连在一起的另一种方法是使用join

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