Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get an array of the values of a key from an array of hashes?

For an array like this:

 a = [{a:'a',b:'3'},{a:'b',b:'2'},{a:'c',b:'1'}]

I would like to return an array containing values for :a keys, so:

 ['a', 'b', 'c']

That can be done using:

 a.map{|x|x[:a]}

I wonder if there is a native method in Rails or Ruby to do it like this?

 a.something :a
like image 731
Arnold Roa Avatar asked Feb 14 '14 22:02

Arnold Roa


2 Answers

You can do it yourself:

class Array
  def get_values(key)
    self.map{|x| x[key]}
  end
end

Then you can do this:

a.get_values :a
#=> ["a", "b", "c"]
like image 80
Mark Thomas Avatar answered Oct 14 '22 13:10

Mark Thomas


More than you need in this case, but from How to merge array of hashes to get hash of arrays of values you can get them all at once:

merged = a.inject{ |h1,h2| h1.merge(h2){ |_,v1,v2| [*v1,*v2] } }
p merged[:a] #=> ["a", "b", "c"]
p merged[:b] #=> ["3", "2", "1"]

Also, if you use something like Struct or OpenStruct for your values instead of hashes—or any object that allows you to get the "a" values as a method that does not require parameters—you can use the Symbol#to_proc convenience for your map:

AB = Struct.new(:a,:b)
all = [ AB.new('a','3'), AB.new('b','2'), AB.new('c','1') ]
#=> [#<AB a="a", b="3">, #<AB a="b", b="2">, #<AB a="c", b="1">]

all.map(&:a) #=> ["a", "b", "c"]
all.map(&:b) #=> ["3", "2", "1"]
like image 24
Phrogz Avatar answered Oct 14 '22 13:10

Phrogz