2011-01-12 19 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の機能に魅了されました。これを書くために多分1行の方法がありますか?この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

あなたはあなたのマップで表現周りの角括弧が欠落しています。結果をスプラットする場合は、 'flatten'への呼び出しもありません。このコードは構文チェックに合格しません。 – Phrogz

+0

あなたは正しいです。私はsplatオペレータで平らにする必要はないと思っていました。私はまた、他のマシンからコピーしたときに角括弧を追加するのを忘れてしまった。 – AboutRuby

+1

'.map.flatten(1)' == '.flat_map' – Nakilon

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 ] 

前者のみHash.[]が2値配列の配列を受信するように許可されているルビー1.8.7+に働きます。後者は、Hash.[]が偶数のパラメータだけを受け取ることが許されていた旧バージョンでも動作します。

2

興味があれば、これはinjectベースのソリューションの外観です。短くないが、もう少しFP-っぽい:

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

または最後の 'acc' – steenslag

+0

はいを​​取り除くために、acc.merge {"#{h.table_name}。#{h.column_name}" => h.position}私はいつもハッシュ自体を返すハッシュ割り当てメソッドの欠如を嫌っていました。 :( –

+0

@steenslagそれは、それぞれの反復で新しいハッシュを作成してしまうという問題があります。「merge!」を使う方がいいですが、それは非常に効率的ではありません。 – Chubas

0

一緒に言葉を結合する別の方法はjoinを使用することです:

positions = Hash.new 
import_profile.headings.each do |h| 
    positions[[h.table_name, h.column_name].join(".")] = h.position 
end 
関連する問題