hitesh israni
hitesh israni

Reputation: 1752

how to work with array of hashes

[[{"Postponed"=>10}], [{"Low"=>3}], [{"Medium"=>4}], [{"High"=>5}]]

is the array

how can I get the value corresponding to particular value.

say High returns 5 in this. or how to convert this array of hashes to an array so that searching becomes easy.

I tried:

find_all { |v| v['name'] == "Low" } 

but it says:

cant convert String to Integer  

please provide some guidance

Upvotes: 2

Views: 873

Answers (5)

william
william

Reputation: 56

If you have some code like:

array = [[{"Postponed"=>10}], [{"Low"=>3}], [{"Medium"=>4}], [{"High"=>5}]]

Then turn it into an ruby hash:

hash = array.inject({}) {|h, e| h.merge(e.first) }
# => {"Postponed"=>10, "Low"=>3, "Medium"=>4, "High"=>5}

So you can find 'Low' value easily :

hash['Low']
# => 3

EDIT: The answer of Mark Thomas is pretty great, and shorter than the inject since it does the same thing. He wrote it before I answered. Nice ;)

Upvotes: 1

Mark Thomas
Mark Thomas

Reputation: 37527

How about making a single hash out of it for efficient querying?

arr.flatten.reduce(:merge)

#=> {"Postponed"=>10, "Low"=>3, "Medium"=>4, "High"=>5}

Upvotes: 9

SimonMayer
SimonMayer

Reputation: 4925

How about this?

  arr = [
    [{"Postponed"=>10}],
    [{"Low"=>3}], 
    [{"Medium"=>4}], 
    [{"High"=>5}]
  ]
  arr1 = []

  arr.each{|a|
    arr1.push(a[0])
  }

Although I wonder if you really just want to get one hash, which you'd do like so:

  myHash = {}

  arr.each{|a|
    a[0].each{|b, c|
      myHash[b] = c
    }
  }

You would then access it like myHash["Postponed"]

Upvotes: 0

Tony Pitale
Tony Pitale

Reputation: 1202

You could simply call #flatten on the original array. That would give you an array of hashes. What I think you would really want is just one hash.

1.8.7 :006 > [[{"Postponed"=>10}], [{"Low"=>3}], [{"Medium"=>4}], [{"High"=>5}]].flatten
=> [{"Postponed"=>10}, {"Low"=>3}, {"Medium"=>4}, {"High"=>5}] 

I would ask, what are you doing to get that original structure? Can that be changed?

Upvotes: 0

John Feminella
John Feminella

Reputation: 311765

In the general case, the hashes won't be unique, so you need to filter rather than pick one via indexing. For example, let's say you have this:

 arr = [[{:apple => 'abc'}], [{:banana => 'def'}], [{:coconut => 'ghi'}]]
 # => [[{:apple=>"abc"}], [{:banana=>"def"}], [{:coconut=>"ghi"}]]

Now let's suppose you want to get the value corresponding to any hash with a :coconut key. Then just use:

 arr.flatten.map { |h| h[:coconut] }.compact
 # => ["ghi"] 

That gives you the list of answers. In this case there's only one matching key, so there's only one entry in the array. If there were other hashes that had a :coconut key in there, then you'd have something like:

 # => ["ghi", "jkl", "mno"]

On the whole, though, that's a very unusual data structure to have. If you control the structure, then you should consider using objects that can return you sensible answers in the manner that you'd like, not hashes.

Upvotes: 1

Related Questions