ブログトップ 記事一覧 ログイン 無料ブログ開設

会者定離で以降 このページをアンテナに追加 RSSフィード

2016-06-15

Hash#mergeにおけるkeyの重複チェック

| 00:11 | Hash#mergeにおけるkeyの重複チェックを含むブックマーク Hash#mergeにおけるkeyの重複チェックのブックマークコメント

 rubyでは、異なる2つのHashをmergeするときに、重複するkeyがあっても上書きされて、特にエラーになったりはしません。

ただ重複が無いはずのHashデータをmergeする場合、仮に重複keyがあればmergeでエラーとなって欲しいので、key重複のチェック方法について検討したメモ書き


重複keyチェック


P.S. 6/18


と下記のように、Setを使ってkeyの重複を調べようと当初考えたが、重複時の動作をblock使うと制御できるのでそれでよい気がするw−、

むやみに、require 'set'もしなくてよいしw−、、、


てか、Hashクラスにモンキーパッチ充てるまでもない気もするので、普通の関数で、以下でどうでしょう?


def merge_strict a,b
  a.merge(b){|key,l,r| raise "key duplicate"}
rescure => e
  p e
  nil
end

P.P.S. 6/18


コメントで、Setに変換せず、そのままArray#&を使えば?っと指摘を受けるが、そうですね、そのままでいいですね^^;


モンキーパッチ版も以下のように簡単になりますね。


class Hash
  def merge_strict other
    unless (self.keys & other.keys).empty?
      nil
    else
      self.merge(other)
    end
  end
end

基本は、Hash#keysで取り出したkey配列をSetに変換し、共通集合が有るかどうかを確認することで、重複チェックが思いついたのでそのようにモンキーパッチーw−



p RUBY_VERSION     #=>"2.1.5"

class Hash
  def merge_strict other
    require 'set'
    
    unless (Set[*self.keys] & Set[*other.keys]).empty?
      nil
    else
      self.merge(other)
    end
  end
end

a =  {a: 1, b: 2}
b =  {c: 3, d: 4}
aa = {a: "foo", aa: "bar", aaa: "baz"}

a.merge b           #=> {:a=>1, :b=>2, :c=>3, :d=>4}
a.merge aa          #=> {:a=>"foo", :b=>2, :aa=>"bar", :aaa=>"baz"}

a.merge_strict b    #=> {:a=>1, :b=>2, :c=>3, :d=>4}
a.merge_strict aa   #=> nil

まあ期待通りうごいてる。重複エラーはnilでなく例外起こしたほうが良いか?

ってかメソッド内部で、requireは良いのだろうか*1


APIリファレンス参考

Hash#merge

no title

Set#intersection

no title

モンキーパッチ

あまりにあまりなモンキーパッチなので、モダンなモンキーパッチを学ばナイト><

分別のあるRubyモンキーパッチャーになるために

メタプログラミング

メタちからを取り戻さないと><

メタプログラミングRuby 第2版
Paolo Perrotta
オライリージャパン
売り上げランキング: 26,971

*1:他に方法思いつかなかった

mas-higamas-higa 2016/06/17 08:46 そのまま self.keys & other.keys だとダメなんでしょうか?

murase_syukamurase_syuka 2016/06/18 16:54 あ、そのままでいけますね^^;
集合演算なのでSetを使いたいお年頃でした><

Connection: close