1

With my array of hashes:

data = [{:bool => true, :val => 5}, {:bool => false, :val => 9}, {:bool => true, :val => 1}]

I would like to iterate through the data and retrieve an array of values only. I can do:

data.map{|x| x[:val] if x[:bool]}

which returns:

[5, nil, 1]

But this method requires an additional .compact call to get rid of the nil values.

Is there a better way of achieving this?

1
  • 3
    Are you sure that you use select and not collect? Commented May 10, 2012 at 17:16

3 Answers 3

6

Use chaining instead to first select only those where :bool is true, then map the results to :val:

data.select { |h| h[:bool] }.map { |h| h[:val] }  #=> [5, 1]
Sign up to request clarification or add additional context in comments.

Comments

1

data.map { |x| x[:val] if x[:bool] }.compact is probably the easiest to read, but you can go down to one function call via reduce:

data.reduce([]) { |m,x| m << x[:val] if x[:bool]; m }

Comments

0

It does not seem an elegant way but you can try this:

data = [{:bool => true, :val => 5}, {:bool => false, :val => 9}, {:bool => true, :val => 1}]
result = Array.new
data.each do |b|
val = Hash.try_convert(b)[:val]
result.unshift(val)
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.