Ruby, iOS, and Other Development

A place to share useful code snippets, ideas, and techniques

All code in posted articles shall be considered public domain unless otherwise noted.
Comments remain the property of their authors.



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 ={|x|x["bar"]}
...or worse...
some_values ={|x|x["bar"]}
other_values ={|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 } }

  def [](key)
    map { |h| h[key] }

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"]
hash = foo.extend(ArrayOfHashes).transpose
some_values,other_values = hash["bar"],hash["baz"]
...respectively. Enjoy!

Labels: ,


Post a Comment

Links to this post:

Create a Link

<< Home