- 更新日: 2014年3月21日
- Ruby
Ruby のハッシュで値が nil の要素を削除して新しいハッシュを返す
スポンサーリンク
Ruby や Rails は、API(メソッド)を知らなくても、オブジェクトに対してそれっぽい操作を適当に書いても、結構動いたりしてくれるからその点はとても楽しいし助かります。
【お知らせ】 英単語を画像イメージで楽に暗記できる辞書サイトを作りました。英語学習中の方は、ぜひご利用ください!
スポンサーリンク
Hash#compact, Hash#compact! はなかった
昨日書いたコードで、値を nil で初期化してある複数の要素からなるハッシュを操作した後、値が nil のままの要素を削除して新しいハッシュを返すようにしたくて、以下のような処理を書いた。Array#compact, compact! はよく使うので、Hash#compact, compact! もあるかな〜と考えまして。
1 2 3 4 |
h = { foo: nil, bar: nil, baz: nil } h[:foo] = "foo" h[:baz] = "baz" h.compact! # => h[:bar] は nil のままなので、{ foo: "foo", baz: "baz" } を返すことを期待したが… |
↓
1 2 3 |
NoMethodError: undefined method `compact!' for {:foo=>"foo", :bar=>nil, :baz=>"baz"}:Hash |
しかし今回は、NoMethodError で残念。なので delete_if を使って書きました。
1 |
h.delete_if{|k, v| v.nil?} # => {:foo=>"foo", :baz=>"baz"} |
delete_if は !(エクスクラメーション)付いてないけど、レシーバ自身を変更する破壊的メソッド。
Hash クラスを拡張して compact, compact! を定義
Ruby はオープンクラスなので、Hash#compact, compact! を定義することもできる。とりあえず簡易的なやつ。
1 2 3 4 5 6 7 8 9 10 |
class Hash def compact! delete_if{ |k, v| v.nil? } end def compact h = self.dup h.delete_if{ |k, v| v.nil? } end end |
組み込み Hash クラスをオープンして、Hash#compact!, Hash#compact の2つのメソッドを追加しました。compact のほうは self を変更しないようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 |
pry(main)> h = {:foo=>"foo", :bar=>nil, :baz=>"baz"} => {:foo=>"foo", :bar=>nil, :baz=>"baz"} pry(main)> g = h.compact => {:foo=>"foo", :baz=>"baz"} pry(main)> h => {:foo=>"foo", :bar=>nil, :baz=>"baz"} pry(main)> g = h.compact! => {:foo=>"foo", :baz=>"baz"} pry(main)> h => {:foo=>"foo", :baz=>"baz"} |
色々自由で Ruby すごい。
スポンサーリンク
私は以下の本で Ruby を覚えました。メタプログラミングRubyは入門を超える内容で難しめです。
>> 次の記事 : Ruby でハッシュの値が nil の場合のみ値を変更して新たなハッシュを返す
<< 前の記事 : Flickr API で Ruby + flickraw を使い画像検索
- Ruby の関連記事
- Gemの作り方(Ruby Gem)
- ローカル開発中のgemをGemfileに書いてインストール
- 熊本地震の余震が夜に多いのは本当か?Rubyプログラムで検証してみた
- El Capitanでgemのnative extensionビルド失敗に対応
- Rubyで親クラスから子クラスの定数を参照
- MacabをRubyで使う
- rbenv/ruby-buildでRuby最新バージョンをインストール
- Rubyでクラスインスタンス変数にインスタンスメソッドからアクセス
- 距離1kmあたりの緯度・経度の度数を計算(日本・北緯35度)
- Google Maps Geocoding APIで住所から緯度・経度を取得するRubyコード
Leave Your Message!