Get a value from an array of hashes in ruby - ruby

I have an array of hashes:
ary = [{1=>"January", 2=>"February", 3=>"March"}, {11=>"Oct", 12=>"Nov", 13=>"Dec"}]
How can I get the value from a particular hash, based on a key? I would like to do something like:
ary[1].select{|h| h[13]}
to get the value "Dec" from the second hash with the key 13. The above statement returns the whole second hash, which is not the requirement:
{11=>"Oct", 12=>"Nov", 13=>"Dec"}

The select statement will return all the hashes with the key 13.
If you already know which hash has the key then the below code will give u the answer.
ary[1][13]
However if you are not sure which of your hashes in the array has the value, then you could do the following:
values = ary.map{|h| h[13]}.compact
Values will have the value of key 13 from all the hashes which has the key 13.

You can merge the two hashes in one and then query the keys of the merged hash.
c = a.merge(b)
=> {1=>"January", 2=>"February", 3=>"March", 11=>"Oct", 12=>"Nov", 13=>"Dec"}
And then you can do something like:
c[1]
=> "January"
Otherwise, if you want to keep the format as an array of different hashes you can just get the value you want this way:
ary[1][12]
=> "Nov"
But that way you have to always know in which hash inside the array is the element you want, which seems a bit confusing because you could just use different hashes instead of an array of hashes and having to remember each hash's position inside the array.

Firstly make a single hash and then return the value of hash by key.
Make single hash from array with merging elements.
Method 1
hash = ary.reduce({}, :merge)
Method 2
hash = ary.inject(:merge)
Then return the value by key.
hash[13]

Related

Better way to loop through a set of hashes assigning array values in Ruby

I am trying to insert data into Postgres. I have an array of data and I am trying to assign each column a value of the array. Here is an example.
pg_insert = ['12/09/2015', 41, 'test account', '41.0']
Table.create([date: pg_insert[0],
account_number: pg_insert[1],
account_name: pg_insert[2],
values: pg_insert[3]])
Is there a way where I can loop this so I can put i in pg_insert instead of having to type out numbers? I'm not sure how to loop inside of the create() parameter. Is there any way around this?
Any suggestions would be great thanks.
Table.create is accepting a Hash, I'm sure.
So here is what you can do:
Make an Array called keys that contains 4 symbols :date, :account_number, :account_name, and :values.
pg_insert is already an Array.
Now you can put the two Arrays together to make the Hash you need: Hash[keys.zip(pg_insert)]
This allows you to call Table.create like this: Table.create(Hash[keys.zip(pg_insert)])
Here is the finished code then:
keys = [:date, :account_number, :account_name, :values]
pg_insert = ['12/09/2015', 41, 'test account', '41.0']
Table.create(Hash[keys.zip(pg_insert)]) # or Table.create Hash[keys.zip(pg_insert)] if you don't want so many parentheses.
Note that pg_insert will always have to be in the same order as keys.
You can read more about Array#zip and Hash.new to understand how those work. This SO link might also be helpful: Converting an array of keys and an array of values into a hash in Ruby

How to check if nested hash attributes are empty

I have a Hash
person_params = {"firstname"=>"",
"lastname"=>"tom123",
"addresses_attributes"=>
{"0"=>
{"address_type"=>"main",
"catalog_delivery"=>"0",
"street"=>"tomstr",
"city"=>"tomcity"
}
}
}
With person_params[:addresses_attributes], I get:
# => {"0"=>{"address_type"=>"main", "catalog_delivery"=>"0", "street"=>"tomstr", "zip"=>"", "lockbox"=>"", "city"=>"tomcity", "country"=>""}}
1) How can I get a new hash without the leading 0?
desired_hash = {"address_type"=>"main", "catalog_delivery"=>"0", "street"=>"tomstr", "zip"=>"", "lockbox"=>"", "city"=>"tomcity", "country"=>""}
2) How can I check whether the attributes in the new hash are empty?
Answer 1:
person_params[:addresses_attributes]['0']
Answer 2:
hash = person_params[:addresses_attributes]['0']
hash.empty?
This looks just like a params hash from Rails =D. Anyway, it seems that your addresses_attributes contains some nested attributes. This means that what you have in practice is more of an array of hashes than a single hash, and that's what you see right? Instead of it being an actually Ruby Array, it is a hash with the index as a string.
So how do you get the address attributes? Well if you only want to get the first address, here are some ways to do that:
person_params[:addresses_attributes].values.first
# OR
person_params[:addresses_attributes]["0"]
In the first case, we will just take the values from the addreses_attributes hash, which gives us an Array from which we can take the first item. If there are no values in addresses_attributes, then we will get nil.
In the second case, we will just ask for the hash value with the key "0". If there are no values in addresses_attributes, we will get nil with this method also. (You might want to avoid using the second case, if you are not confident that the addresses_attributes hash will always be indexed from "0" and incremented by "1")

How to iterate or map over a Ruby Hash to change one specific value?

Is there a way iterate or map over the hash below so that you can add the deposit variable to the value 0 of the "john"=>0 key/value pair?
I commented the desired output below.
deposit = 20
Hash = {"Mike"=>0, "John"=>0, "Jen"=>0}
# I would like the result to look like Hash = {"Mike"=>0, "John"=>20, "Jen"=>0}
First, your constant name Hash will mess up many things. Understanding that,
Hash["John"] += deposit

checking if all values of a hash are correct values (from a predefined value set) in ruby

I have a hash table with multiple values being passed to a function I dont know the names of the keys but i know that the values of the keys must be equal to characters A S or X.
How can i easily check that all values in the hash table are equal to those characters?
NullUserException is good, you could also
match_values = %w(A S X)
hash.values.all? { |value| match_values.include?(value) }

Return a single key from a Hash?

I would like to know how to return a specific key from a Hash?
Example:
moves = Hash["Kick", 100, "Punch", 50]
How would I return the first key "Kick" from this Hash?
NOTE: I'm aware that the following function will return all keys from the hash but I'm just interested in returning one key.
moves.keys #=> ["Kick", "Punch"]
You can use:
first_key, first_value = moves.first
Or equivalently:
first_key = moves.first.first
Quite nice too:
first_key = moves.each_key.first
The other possibility, moves.keys.first will build an intermediary array for all keys which could potentially be very big.
Note that Ruby 1.8 makes no guarantee on the order of a hash, so the key you will get not always be the same. In Ruby 1.9, you will always get the same key ("Kick" in your example).
moves.keys[0]
will give you the first key.
You can get all keys by changing the argument passed (0, 1,...etc)
moves.keys.first will accomplish that.

Resources