Python の内包表記とRuby のブロック
Pythonista が Ruby に優越感を抱くのに、内包表記の存在がある。内包表記は select + map でいけるし、日本人としてはあまり読みやすいとは思えない(内包表記は英語だと語順が自然)ので、Ruby 風に書くと確かに冗長だけれども、Ruby には採用しないみたいなことを Matz は書いていた。確かにちょっと冗長かな。ある本に Python の
{x:str(y * y) for x, y in {1:2, 3:4}.items()}}
を Ruby へ
{1=>2, 3=>4}.inject({}) do |result, key_value| result[key_value[0]] = (key_value[1] ** 2).to_s result end
と翻訳してあった。さすがにこれは変数名と行分けに悪意を感じる。比較するなら
{1=>2, 3=>4}.inject({}) {|h, (x, y)| h[x] = (y ** 2).to_s; h}
ではないの? それから、冗長にはちがいないけれど
(h = {1=>2, 3=>4}).each_key {|x| h[x] = (h[x] ** 2).to_s}
とも書ける。Ruby 2.1 以降なら
{1=>2, 3=>4}.map {|x, y| [x, (y ** 2).to_s]}.to_h
とかね。これなら(読みやすさで)内包表記にそれほど劣るとは思えない。
- 作者: 細田謙二,石井光次郎,岩川建彦,岡田正彦,オレンジ岸本,エスキュービズム
- 出版社/メーカー: 秀和システム
- 発売日: 2010/06/24
- メディア: 単行本
- 購入: 6人 クリック: 189回
- この商品を含むブログ (20件) を見る
module Enumerable def maph(&bl) map(&bl).to_h end end {1=>2, 3=>4, 5=>6}.maph {|k, v| [k, (v ** 2).to_s]} #=>{1=>"4", 3=>"16", 5=>"36"}
とかあってもよさそうな気が。いや、いらんな…。
※追記
以下でもよい。
{1=>2, 3=>4}.each_with_object({}) {|x, h| h[x[0]] = (x[1] ** 2).to_s}
色いろありますな。(11/10)