ArrayOfHashes
More often than I might have expected I wind up dealing with arrays of hashes. A lot of this comes from making JSON-RPC calls, incidentally, but that doesn't matter. The important thing is that I kept writing code like this:
values = foo.map{|x|x["bar"]}...or worse...
some_values = foo.map{|x|x["bar"]} other_values = foo.map{|x|x["baz"]}
I came to the conclusion that what I really wanted was a way to treat arrays of hashes in a special way, and that means mixing in a module! Here's the ArrayOfHashes module:
module ArrayOfHashes def transpose hash = {} each_with_index { |h,i| h.each { |k,v| (hash[k] ||= [])[i] = v } } hash end def [](key) map { |h| h[key] } end end
It's pretty simple, actually. Array#transpose assumes it's an array of arrays, so this just overrides it with the assumption that it's an array of hashes. The result is a hash of arrays, generated in the spirit of the original Array#transpose. Overriding the [] operator is a little bit weirder, but it is (nearly) equivalent to using transpose[] without doing the full transpose.
So now those two examples become...
values = foo.extend(ArrayOfHashes)["bar"]...and...
hash = foo.extend(ArrayOfHashes).transpose some_values,other_values = hash["bar"],hash["baz"]...respectively. Enjoy!