Les Is More
Updated: February 2008
I often need a hash of arrays in Ruby. So for example, I can have:
months = {"Feb"=>["Article1", "Article2", "Article3"],
"Mar"=>["Article4", "Article5"]}
Now if I am reading through an array of articles, I can set up my hash like so:
class Article attr_accessor :name, :month def initialize(name, month) @name = name @month = month end end articles = [ Article.new("Article1", "Feb"), Article.new("Article2", "Feb"), Article.new("Article3", "Feb"), Article.new("Article4", "Mar"), Article.new("Article5", "Mar"), ] months = {} articles.each do |a| months[a.month] ||= [] months[a.month] << a.name end p months
This works great. For each article, we set a specific hash key to an empty array, but only if it is currently nil. That's what this does:
months[a.month] ||= []
Then we add the article's name to the array:
months[a.month] << a.name
There are more ways of doing that which might be better. You can combine the two lines:
months = {}
articles.each do |a|
(months[a.month] ||= [])<< a.name
end
Another way is to provide a default for new hash values. When we create the hash (months = {}), we can specify a block which Ruby will use to generate default values in the hash. This makes things nicer:
months = Hash.new{|h, k| h[k] = []} articles.each do |a| months[a.month] << a.name end
Also, this way is a bit faster, since theoretically we are not testing each hash element for emptiness each time we add a value to the array. A benchmark does indeed show it to be slightly faster - though you need truly huge arrays to see any difference.
This is the website of Leslie Viljoen. I am a Disciple, Husband, Dad, Programmer, Gamer, Geek, Writer, Biker, Gardner. Perhaps even in that order. I currently live in Auckland, New Zealand.

In 2011 I moved to Auckland and began working for
TrifectaGIS, writing mostly Ruby and Rails code. I love my work!
Comments are welcome! Contact me AT gmail, using the
address "leslieviljoen".
2011
May
April
2008
May
February
2007
May
March
Darwin
Diabetes
Interactive Fiction
Meta
Ruby
Ubuntu