Created
May 6, 2012 20:14
-
-
Save granolocks/2624185 to your computer and use it in GitHub Desktop.
Multi-value hashes in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Multi-value hashes in Ruby | |
# Posted on March 24, 2011 | |
# http://matthew.mceachen.us/blog/multi-value-hashes-in-ruby-1114.html | |
# Any non-trivial project quickly finds itself needing data structures that are more exotic than simple arrays or maps. In my quest for multimap | |
# nirvana, I first found references where every value-put call would need to be changed to look like this: | |
h = {} | |
(h[:key] ||= []) << "value 1" | |
(h[:key] ||= []) << "value 2" | |
puts h | |
#=> {:key=>["value 1", "value 2"]} | |
# Obviously, not DRY, and painful to look at. I came across this post which talks about using the hash constructor: | |
h = Hash.new{|h,k| h[k] = []} | |
h[:key] << "value 1" | |
h[:key] << "value 2" | |
puts h | |
#=> {:key=>["value 1", "value 2"]} | |
# OK, I think I can live with that. | |
# If you want a multi-value hash whose values are never duplicated, use Set.new in the constructor instead of an array. | |
# If you need arbitrary-depth hashes, though, check this out: | |
h = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) } | |
h[:a][:b][:c] = "123" | |
puts h | |
#=> {:a=>{:b=>{:c=>"123"}}} | |
# The default_proc mechanics are explained very well here: http://railsforum.com/viewtopic.php?pid=113682#p113682. | |
# Comment: "this is called autovivification ;)" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment