How can I get the values of hash using a key array? - ruby

I want to get all value of a hash using an array containing the keys?
I have this hash:
{:id=>402, :email=>"tyson#ledner.name", :organizations_count=>0, :username=>"admin"}
I have an array :
[:id, :email]
So I want to get an array of
["402", "tyson#ledner.name"]
Is there a cleaver way to do this? I have a loop but I feel ruby can do this in a "oneliner" way but can figure out how to do this.

You should use Hash#values_at:
hash = {:id=>402, :email=>"tyson#ledner.name", :organizations_count=>0, :username=>"admin"}
array = [:id, :email]
hash.values_at(*array)
#=> [402, "tyson#ledner.name"]
Passing array with splat operator (*) as argument in this case is same as just hash.values_at(:id, :email)

Related

Convert array of hashes to single hash with values as keys

Given a source array of hashes:
[{:country=>'england', :cost=>12.34}, {:country=>'scotland', :cost=>56.78}]
Is there a neat Ruby one-liner for converting it to a single hash, where the values for the :country key in the original hash (guaranteed to be unique) become keys in the new hash?
{:england=>12.34, :scotland=>56.78}
This should do what you want
countries.each_with_object({}) { |country, h| h[country[:country].to_sym] = country[:cost] }
=> {:england=>12.34, :scotland=>56.78}
You can do that using Enumerable#inject:
countries.inject({}) { |hsh, element| hsh.merge!(element[:country].to_sym => element[:cost]) }
=> {:england=>12.34, :scotland=>56.78}
We initialise the accumulator as {}, and then we iterate over each of the elements of the initial array and add the new formatted element to the accumulator.
One point to add is that using hsh.merge or hsh.merge! would have the same effect for the output, given that inject will set the accumulator hsh as the return value from the block. However, using merge! is better when it comes to memory usage, given that merge will always generate a new Hash, whereas merge! will apply the merge over the same existing Hash.
One more possible solution is:
countries.map(&:values).to_h
=> {"england"=>12.34, "scotland"=>56.78}

How to get the index of a key in a hash?

I'm trying to get the index of a key in a hash.
I know how to do this in an array:
arr = ['Done', 13, 0.4, true]
a = arr.index('Done')
puts a
Is there a method or some sort of way to do this something like this with a key in a hash? Thanks!
Hashes aren't usually treated as ordered structures, they simply have a list of keys and values corresponding to those keys.
It's true that in Ruby hashes are technically ordered, but there's very rarely an actual use case for treating them as such.
If what you want to do is find the key corresponding to a value in a hash, you can simply use the Hash#key method:
hash = { a: 1, b: 2 }
hash.key(1) # => :a
I suppose you could use hash.keys.index(hash.key(1)) to get 0 since it's the first value, but again, I wouldn't advise doing this because it's not typical use of the data structure
There are at least a couple ways you can get this information, the 2 that come to mind are Enumerable's find_index method to pass each element to a block and check for your key:
hash.find_index { |key, _| key == 'Done' }
or you could get all the keys from your hash as an array and then look up the index as you've been doing:
hash.keys.index('Done')

Get all keys from ruby hash

In php you can just do $associative_array_keys = array_keys($associative_array)
Is there a function to get all hash keys in ruby?
I'm currently mapping my hashes and returning the keys: my_hash_keys = my_hash.map{|k,v| k}
Is there a better solution?
You can call .keys on a Hash to get an array of keys back.
See: Hash#keys

How to save an array of information coming from a hash in Ruby

I am new to ruby and don't have much experience with hashes, I have a variable named tweets and it is a hash as such:
{"statuses"=>[{"metadata"=>{"result_type"=>"recent", "iso_language_code"=>"tl"}, "lang"=>"tl"}]}
I would like to save the array of information as a separate variable in an array. How would I go about this?
Hash's have 2 very nice methods,
hash.values
hash.keys
in your case -
h = {"statuses"=>[{"metadata"=>{"result_type"=>"recent", "iso_language_code"=>"tl"}, "lang"=>"tl"}]}
p h.values
p.keys
These output arrays of each type. This might be what you want.
Also, this question will very well be closed. 1 Google search reported several Hash to Array SO questions.
Ruby Hash to array of values
Converting Ruby hashes to arrays
If you have a Hash like so:
hash = {:numbers => [1,2,3,4]}
And you need to capture the array into a new variable. You can just access the key and assign it to a new variable like so:
one_to_five = hash[:numbers]
However, note that the new variable actually holds the array that is in the hash. So altering the hash's array alters the new variable's array.
hash[:numbers] << 6
puts one_to_five #=> [1,2,3,4,5,6]
If you use dup, it will create a copy of the array so it will be two separate arrays.
one_to_five = hash[:numbers].dup
hash[:numbers] << 6
puts one_to_five #=> [1,2,3,4,5]
So, in your case:
hash = {'statuses' => [{"metadata"=>{"result_type"=>"recent", "iso_language_code"=>"tl"}, "lang"=>"tl"}]}
new_array = hash['statuses'].dup
However, it would be interesting to see what it is you are wishing to accomplish with your code, or at least get a little more context, because this may not be the best approach for your final goal. There are a great many things you can do with Arrays and Hashes (and Enumerable) and I would encourage you to read through the documentation on them.

Why does hash.keys.class return Arrays?

New to Ruby, I'm just missing something basic here. Are the keys in a Hash considered an Array unto themselves?
Yes, Hash#keys returns the hash's keys as a new array, i.e., the hash and the array returned by Hash#keys are completely independent of each other:
a = {}
b = a.keys
c = a.keys
b << :foo
a # still {}
b # [:foo]
c # still []
a[:bar] = :baz
a # {:bar => :baz}
b # still [:foo]
c # still []
From the documentation of hash.keys:
Returns a new array populated with the keys from this hash. See also Hash#values.
So the class is Array because the return value is an array.
About your question "Are the keys in a Hash considered an Array unto themselves?", they "kind" of are, hashes in Ruby are implemented as struct (st_table) which contains a list of pointers to each of its entries(st_table_entry),the st_table_entry contains the key and its value, so I guess what the keys method does is just transversing that list taking out each of the keys.
You can read this article of Ilya Grigorik where he explains much better Hashes in Ruby http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/
Do you think there's something paradoxical about this? Keep in mind that hashes aren't arrays in Ruby.

Resources