Get specific values from an array of hashes in Ruby

quick tip header

Let’s say you have an array of hashes like this in Ruby:

books = [
  { title: "Book 1", length: 400, genre: "Fiction" },
  { title: "Book 2", length: 300, genre: "Non-fiction"},
  { title: "Book 3", length: 425, genre: "Sci-Fi"}
]

How can you get all of the titles? Let’s use the map method:

books.map { |b| b[:title] }
# ["Book 1", "Book 2", "Book 3"]

What about if you want the length too?

books.map { |b| [b[:title], b[:length]] }
# [["Book 1", 400], ["Book 2", 300], ["Book 3", 425]]

But what if you want to include the keys?

books.map { |b| { title: b[:title], length: b[:length] } }
# [{:title=>"Book 1", :length=>400}, {:title=>"Book 2", :length=>300}, {:title=>"Book 3", :length=>425}]

There’s a cleaner way to do that same operation using the Hash slice method:

books.map { |b| b.slice(:title, :length) }
# [{:title=>"Book 1", :length=>400}, {:title=>"Book 2", :length=>300}, {:title=>"Book 3", :length=>425}]

If you’re using Rails with an ActiveRecord relation (instead of an array of hashes), you can use the select method to simplify it further:

books.select(:title, :length)
# [{:title=>"Book 1", :length=>400}, {:title=>"Book 2", :length=>300}, {:title=>"Book 3", :length=>425}]

☝️ This is a bit different since you’re choosing columns with select, but the result is the same.