Kert
Kert

Reputation: 1614

Collect values from an array of hashes

I have a data structure in the following format:

data_hash = [
    { price: 1, count: 3 },
    { price: 2, count: 3 },
    { price: 3, count: 3 }
  ]

Is there an efficient way to get the values of :price as an array like [1,2,3]?

Upvotes: 78

Views: 74758

Answers (3)

Kalsan
Kalsan

Reputation: 1039

If using Rails, you may also use the following solution, because Rails patches the class Enumerable:

array = [
    {:price => 1, :count => 3},
    {:price => 2, :count => 3},
    {:price => 3, :count => 3}
]

array.pluck(:price)

#=> [1, 2, 3]

Reference: https://api.rubyonrails.org/classes/Enumerable.html#method-i-pluck

Unfortunately, the implementation is pure ruby, so I wouldn't expect an increase in speed.

Upvotes: 5

adc
adc

Reputation: 557

There is a closed question that redirects here asking about handing map a Symbol to derive a key. This can be done using an Enumerable as a middle-man:

array = [
    {:price => 1, :count => 3},
    {:price => 2, :count => 3},
    {:price => 3, :count => 3}
]

array.each.with_object(:price).map(&:[])

#=> [1, 2, 3] 

Beyond being slightly more verbose and more difficult to understand, it also slower.


Benchmark.bm do |b| 
  b.report { 10000.times { array.map{|x| x[:price] } } }
  b.report { 10000.times { array.each.with_object(:price).map(&:[]) } }
end

#       user     system      total        real
#   0.004816   0.000005   0.004821 (  0.004816)
#   0.015723   0.000606   0.016329 (  0.016334)

Upvotes: 4

Zabba
Zabba

Reputation: 65467

First, if you are using ruby < 1.9:

array = [
    {:price => 1, :count => 3},
    {:price => 2, :count => 3},
    {:price => 3, :count => 3}
]

Then to get what you need:

array.map{|x| x[:price]}

Upvotes: 135

Related Questions