Skip to content

Instantly share code, notes, and snippets.

@igaiga
Created July 18, 2017 09:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save igaiga/58abe028148ad1a7235c3c46265c5518 to your computer and use it in GitHub Desktop.
Save igaiga/58abe028148ad1a7235c3c46265c5518 to your computer and use it in GitHub Desktop.
h = {}
["a", "a", "b"].each do |x|
h[x] = [] unless h[x]
h[x] << x
end
p h
#=> {"a"=>["a", "a"], "b"=>["b"]}
@kaznum
Copy link

kaznum commented Jul 18, 2017

キレイかどうかは別として

  %w(a a b).inject( {}.tap{ |h| h.default_proc = -> (hash, k) { hash[k] = [] } } ) do |acc, x|
    acc.tap{|a| a[x] << x }
  end

つまりは、default_procを使うのではどうでしょう。

@cesare
Copy link

cesare commented Jul 18, 2017

h = {}
["a", "a", "b"].each do |x|
  (h[x] ||= []) << x
end

とかですかねー。地味ですが 😅

@ko1
Copy link

ko1 commented Jul 18, 2017

h = Hash.new{|h, k| h[k] = []}
["a", "a", "b"].each do |x|
  h[x] << x
end
p h
#=> {"a"=>["a", "a"], "b"=>["b"]}

@igaiga
Copy link
Author

igaiga commented Jul 18, 2017

うわー、たくさんのご回答ありがとうございます!
twitterでの回答
いっくんさんとえむさんのコンストラクタ使うパターン。ko1さんもこのパターンですね。
https://twitter.com/alpaca_tc/status/887284633536086017
Hash.new { |h, k| h[k] = [] }

@igaiga
Copy link
Author

igaiga commented Jul 18, 2017

hidaqaさん、よしだあつしさんのgroup_byパターン。まったく発想になかった。
https://twitter.com/hidaqa/status/887442669969874944
p ["a", "a", "b"].group_by {|x| x }

@igaiga
Copy link
Author

igaiga commented Jul 19, 2017

私は h = Hash.new([].dup) で書けるのかなと思って書いてみたのですが、思った通り動かなくて質問した、という流れでした。

# 想定とは違った
h = Hash.new([].dup)
p h["a"].object_id #=> 70343972755460
h["a"] << "a"
p h["a"].object_id #=> 70343972755460
h["a"] << "a"
p h["a"] #=> ["a", "a"]
p h #=> {} #←?
# 想定通り
h = Hash.new{|h, k| h[k] = []}
p h["a"].object_id #=> 70278001603780
h["a"] << "a"
p h["a"].object_id #=> 70278001603780
h["a"] << "a"
p h["a"] #=> ["a", "a"]
p h #=> {"a"=>["a", "a"]} #←わかる

@nobu
Copy link

nobu commented Jul 23, 2017

default_proc で代入すると意図していないところでも勝手に追加されるので、追加するところで代入するとか

h["a"] <<= "a"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment