破いて捨てたノート

Webやテクノロジーやそれ以外に関する思いつき

RubyのArrayとかHashのuniqueに関する挙動のメモ

RubyのArrayにはuniqってメソッドがあるじゃん?

irb(main):001:0> [:foo, :bar, :baz, :foo]
=>  [:foo, :bar, :baz, :foo]

irb(main):002:0> [:foo, :bar, :baz, :foo].uniq
=> [:foo, :bar, :baz]

この辺はあたりまえだが、 たまにお世話になる多重配列になると脳内インタプリタの挙動が怪しかった。

irb(main):003:0> [[:foo, 1], [:foo, 2]].uniq
=> [[:foo, 1], [:foo, 2]]
irb(main):004:0> [[:foo, 1], [:bar, 1]].uniq
=> [[:foo, 1], [:bar, 1]]
irb(main):005:0> [[:foo, 1], [:foo, 1]].uniq
=> [[:foo, 1]]

結果を見れば当たり前といった感じだった。 ちなみに、Hashはこんな風に動くらしいっす。

# 当たり前
irb(main):006:0> { foo: 1, bar: 2, foo: 1 }
=> {:foo=>1, :bar=>2}

# ココ重要
irb(main):007:0> { foo: 1, bar: 2, foo: 2 }
=> {:foo=>2, :bar=>2}
# もう一回
irb(main):008:0> { foo: 1, bar: 2, foo: 2 }
=> {:foo=>2, :bar=>2}

keyとvalueがともに重複する場合は、ランダムではなく後方の値に上書きされるらしい(?)

ちなみに、どうしても1つにkeyに複数のvalueを持たせたかったら、

irb(main):009:0> h = Hash.new { |h, k| h[k] = [] }
=> {}
irb(main):010:0> h[:foo] << :bar
=> [:bar]
irb(main):011:0> h[:foo] << :baz
=> [:bar, :baz]
irb(main):012:0> h
=> {:foo=>[:bar, :baz]}

って書けばいいらしいよ!

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)