Ruby get object keys as array - ruby

I am new to Ruby, if I have an object like this
{"apple" => "fruit", "carrot" => "vegetable"}
How can I return an array of just the keys?
["apple", "carrot"]

hash = {"apple" => "fruit", "carrot" => "vegetable"}
array = hash.keys #=> ["apple", "carrot"]
it's that simple

An alternative way if you need something more (besides using the keys method):
hash = {"apple" => "fruit", "carrot" => "vegetable"}
array = hash.collect {|key,value| key }
obviously you would only do that if you want to manipulate the array while retrieving it..

Like taro said, keys returns the array of keys of your Hash:
http://ruby-doc.org/core-1.9.3/Hash.html#method-i-keys
You'll find all the different methods available for each class.
If you don't know what you're dealing with:
puts my_unknown_variable.class.to_s
This will output the class name.

Use the keys method: {"apple" => "fruit", "carrot" => "vegetable"}.keys == ["apple", "carrot"]

Related

How to print only a value in key value pair

This is my code
lunch_order = {
"Ryan" => "wonton soup",
"Eric" => "hamburger",
"Jimmy" => "sandwich",
"Sasha" => "salad",
"Cole" => "taco"
}
lunch_order.each { |element| puts element }
I want the value to be printed out, but here, both the value and the key are printed.
You can use
lunch_order.each { |key, value| puts value}
Codepad Example
You can loop over the values only with each_value
h = { "a" => 100, "b" => 200 }
h.each_value {|value| puts value }
You can read more about api of hash here.
So many ways to do it in Ruby:
lunch_order.values.each { |element| puts element }
In Ruby a hash contains Keys and Values. So in your case the keys are:
Keys
Ryan
Eric
Jimmy
Sasha
Cole
And the Values for those keys are:
Values
Wonton Soup
Hamburger
Sandwich
Salad
Taco
And all you'd need to do to call the values is use the each loops like you've done but instead of using element as the local variable within the block, you use something like this:
lunch_order.each do { |key, value| puts value }
lunch_order.each_pair { |key,value| puts value }
Docs: http://apidock.com/ruby/Hash/each_pair
Given your original code
lunch_order = {
"Ryan" => "wonton soup",
"Eric" => "hamburger",
"Jimmy" => "sandwich",
"Sasha" => "salad",
"Cole" => "taco"
}
You created a hash, which consists of both keys and values. Keys are on the left, values on the right. To get only the values use
lunch_order.values.each{|value| puts value}
Hope this helps.

Clean way to search through hash keys in Ruby

I have a hash like so:
hash = {"jonathan" => "12", "bob" => 15 }
Then I have an array like so:
array = ['jon', 'bob']
I want to return the value of the key that includes a value in my array in the end.
The goal is something like this:
array.each do |name|
if hash.key.include? name
return hash.value
end
What's the best way to write that code block?
If you want multiple values, use Hash#values_at:
hash = {"jonathan" => "12", "bob" => 15 }
array = ['jon', 'bob']
hash.values_at(*array.select{|key| hash.has_key? key})
# => [15]
Using Array#&:
hash.values_at(*(hash.keys & array))
# => [15]
To get the keys, you don't need a block, this will do:
hash.keys & array
This takes the keys of the hash and intersect it with the array.
Second part, get a value from the hash:
hash[(hash.keys & array).last]
This will get the last key that is shared in hash and array and returns the value of that key in hash.
Also you can use select methods of Hash:
hash.select {| k,_ | array.include?( k ) }
# => {"bob"=>15}
and get, for example, last value:
hash.select {| k,_ | array.include?( k ) }.to_a.flatten.last
# => 15
or even use values_at method of Hash:
hash.values_at( *array ).compact.last
# => 15
Here is how I would write :
hash = {"jonathan" => "12", "bob" => 15 }
array = ['jon', 'bob']
array.collect(&hash.method(:[])).compact # => [15]

Accessing hash values by methods vs like in array in ruby

I have a hash like this:
h = { "key1" => { "key2" => "value"}, "key3" => "value3"}
If I try to access h.key1 it won't let me, but if I do h["key1"] it will.
But when I use the session hash, I can write the following code without getting an error:
#session = session["omniauth"]
#session.data
When can I access the keys by methods and when like an array?
You can only access hash values with h["key1"] method (without using other modifiers).
The reason why #session.data works is that #session is not an instance of Hash, but its an instance of OmniAuth::AuthHash which supports both methods to access values.
So it depends on a type of an object you are working with.
You can access hash key by dot notation with the help of OpenStruct
require 'ostruct'
h = { "key1" => { "key2" => "value"}, "key3" => "value3"}
open_struct = OpenStruct.new(h)
p open_struct.key1
I hope It may help you to solve your issue
The reason you are able to access key-value from the session object is that someone has defined the method [] on it.
If you wanted to access h.key1 on your hash, use OpenStruct:
h = OpenStruct({ "key1" => { "key2" => "value"}, "key3" => "value3"})
This would return the following results:
h.key1 # { "key2" => "value }
h.key3 # "value3"

Creating array of hashes in ruby

I want to create an array of hashes in ruby as:
arr[0]
"name": abc
"mobile_num" :9898989898
"email" :abc#xyz.com
arr[1]
"name": xyz
"mobile_num" :9698989898
"email" :abcd#xyz.com
I have seen hash and array documentation. In all I found, I have to do something
like
c = {}
c["name"] = "abc"
c["mobile_num"] = 9898989898
c["email"] = "abc#xyz.com"
arr << c
Iterating as in above statements in loop allows me to fill arr. I actually rowofrows with one row like ["abc",9898989898,"abc#xyz.com"]. Is there any better way to do this?
Assuming what you mean by "rowofrows" is an array of arrays, heres a solution to what I think you're trying to accomplish:
array_of_arrays = [["abc",9898989898,"abc#xyz.com"], ["def",9898989898,"def#xyz.com"]]
array_of_hashes = []
array_of_arrays.each { |record| array_of_hashes << {'name' => record[0], 'number' => record[1].to_i, 'email' => record[2]} }
p array_of_hashes
Will output your array of hashes:
[{"name"=>"abc", "number"=>9898989898, "email"=>"abc#xyz.com"}, {"name"=>"def", "number"=>9898989898, "email"=>"def#xyz.com"}]
you can first define the array as
array = []
then you can define the hashes one by one as following and push them in the array.
hash1 = {:name => "mark" ,:age => 25}
and then do
array.push(hash1)
this will insert the hash into the array . Similarly you can push more hashes to create an array of hashes.
You could also do it directly within the push method like this:
First define your array:
#shopping_list_items = []
And add a new item to your list:
#shopping_list_items.push(description: "Apples", amount: 3)
Which will give you something like this:
=> [{:description=>"Apples", :amount=>3}]

use regex as keywords in ruby hash

I have hash mapping
H = {
"alc" => "AL",
"alco" => "AL",
"alcoh" => "AL",
"alcohol" => "AL",
"alcoholic" => "AL",
}
now I want to use a regex to represent all the keys, like
H={
/^alc/ => "AL"
}
later on I want to use H["alc"] or H["alco"] to retrieve the value. But if I use regex, I can not get the value properly. What should I do?
class MyHash < Hash
def [](a)
self.select {|k| k =~ a}.shift[1]
end
end
result = MyHash.new
result[/^alc/] = "AL"
puts result['alcohol'] #=> 'AL'
I would create a subclass of the hash and then over write this method. This way you can still keep the regular hash functionality elsewhere.
Make a subclass, inherit Hash class and override [] behaviour so it checks whether it matches each regex in your hash and returns the corresponding value.

Resources