Jeff Dickey
Jeff Dickey

Reputation: 5034

Is there a clean way to access hash values in array of hashes?

In this code:

arr = [ { id: 1, body: 'foo'}, { id: 2, body: 'bar' }, { id: 3, body: 'foobar' }]
arr.map { |h| h[:id] } # => [1, 2, 3]

Is there a cleaner way to get the values out of an array of hashes like this?

Underscore.js has pluck, I'm wondering if there is a Ruby equivalent.

Upvotes: 17

Views: 18675

Answers (3)

Ghis
Ghis

Reputation: 913

Unpopular opinion maybe, but I wouldn't recommend using pluck on Array in Rails projects since it is also implemented by ActiveRecord and it behaves quite differently in the ORM context (it changes the select statement) :

User.all.pluck(:name) # Changes select statement to only load names
User.all.to_a.pluck(:name) # Loads the whole objects, converts to array, then filters the name out

Therefore, to avoid confusion, I'd recommend using the shorten map(&:attr) syntax on arrays:

arr.map(&:name)

Upvotes: 1

khaled_gomaa
khaled_gomaa

Reputation: 3412

Now rails support Array.pluck out of the box. It has been implemented by this PR

It is implemented as:

def pluck(key)
  map { |element| element[key] }
end

So there is no need to define it anymore :)

Upvotes: 14

Ken Y-N
Ken Y-N

Reputation: 15009

If you don't mind monkey-patching, you can go pluck yourself:

arr = [{ id: 1, body: 'foo'}, { id: 2, body: 'bar' }, { id: 3, body: 'foobar' }]

class Array
  def pluck(key)
    map { |h| h[key] }
  end
end

arr.pluck(:id)
=> [1, 2, 3]
arr.pluck(:body)
=> ["foo", "bar", "foobar"]

Furthermore, it looks like someone has already generalised this for Enumerables, and someone else for a more general solution.

Upvotes: 30

Related Questions