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 endP.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
Set#intersection
*1:他に方法思いつかなかった