why there is a column ":" in front of key in ruby [duplicate] - ruby

This question already has answers here:
Is there any difference between the `:key => "value"` and `key: "value"` hash notations?
(5 answers)
Closed 1 year ago.
aaa = { :one => "eins", :two => "zwei", :three => "drei" }
bbb = { one: "eins", two: "zwei", three: "drei" }
above are valid ruby code. at line 1, why there is ":" before "one"? What's the meaning?

It's called Symbol, you could think of it as a special string. Symbols are often used as hash keys.
You could check out more on Ruby Symbols vs. Strings

In ruby hash is an association of key and value.
my_hash = { :key => "value" }
or
my_hash = { key: "value" }
more informations here : https://launchschool.com/books/ruby/read/hashes

Related

Ruby: what's the difference using property with colons and quotes

I'm a newbie on Ruby, just doing a fast upgrade in a existent project and I'm wondering what's the difference between object record and to_validate.
puts to_validated.class
# Hash
puts to_validated
# {"data"=>{"name"=>"david"}, "metadata"=>{"body_size"=>"16", "collector_ip"=>"172.22.0.1", "collector_timestamp"=>1579608324863, "event"=>"whatever", "version"=>"1.0"}}
puts record.class
# Hash
puts record
# {:data=>{"name"=>"david"}, :metadata=>{"body_size"=>"16", "collector_ip"=>"172.22.0.1", "collector_timestamp"=>1579610268940, "event"=>"default", "version"=>"1.0.0"}}
The only difference on those objects is colons on data and metadata. Is possible to convert colons into quotes?
I know it's a dumb question but I'm applying a fix in this project and using a third party library that is failing using record object.
You can use Hash.transform_keys which was introduced to Ruby in version 2.5 to change symbolized keys into strings:
record.transform_keys { |k| k.to_s }
In Ruby hashes are a key value data structure. The keys can actually be a mix of any kind of objects:
hash_with_numerical_keys = {
1 => 'A',
2 => 'B',
3 => 'C'
3.5 => 'D'
}
hash_with_string_keys = {
'a' => 1,
'b' => 2,
'c' => 3
}
hash_with_symbols = {
:a => 1,
:b => 2,
:c => 3
}
# can also be declared as
hash_with_symbols = {
a: 1,
b: 2,
c: 3
}
hash_with_singletons = {
nil => 0,
true => 1,
false => 2
}
Symbols are commonly used as only one instance of a symbol ever exists. They are thus really effective to compare. String keys mostly come into play when you're dealing with JSON or some kind of external data.
The hash you are looking at contains a mixture of string and symbol keys:
{:data=>{"name"=>"david"}, :metadata=>{"body_size"=>"16", "collector_ip"=>"172.22.0.1", "collector_timestamp"=>1579610268940, "event"=>"default", "version"=>"1.0.0"}}
In Ruby 2.5 you can use hash#transform_keys to change the keys into strings:
hash.transform_keys(&:to_s)
In earlier versions you can do:
hash.each_with_object({}) do |(k,v), new_hash|
new_hash[k.to_s] = v
end
If you are using Rails or just ActiveSupport you can use Hash#stringify_keys, Hash#deep_stringify_keys or HashWithIndifferentAccess

colon placement in Ruby 2.2+ [duplicate]

This question already has answers here:
Is there any difference between the `:key => "value"` and `key: "value"` hash notations?
(5 answers)
Closed 7 years ago.
I see colons used two different ways in Ruby
:controller => 'pages'
and then
action: => 'home'
I found an explanation here: http://goo.gl/ZKxKVK
it seems that the position doesn't matter, could someone clarify this?
Mostly it doesn't matter. Since Ruby 1.9 we can use more short form:
h = { a: 1, b: 2}
But there are some situations where you have to use the longest form, e.g.:
h = {1 => 'a', 2 => 'b'}
h = {"One Two" => 1}
action: => 'home' is not valid syntax.
It should be action: 'home' or :action => 'home'.
These are equivalent. They generate:
{:action=>'home'}

How does this definition for a hash work? [duplicate]

This question already has answers here:
Is there any difference between the `:key => "value"` and `key: "value"` hash notations?
(5 answers)
Closed 8 years ago.
I found code with hash assignment such as follows:
#defeat = {r: :s, p: :r, s: :p}
# => {:r=>:s, :p=>:r, :s=>:p}
Why are the keys for this hash generated as symbols? Is this a short form of doing this?
defeat[:r] = :s
defeat[:p] = :r
defeat[:s] = :p
Is there a name for this style of Hash?
A Hash can be easily created by using its implicit form:
grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
Hashes allow an alternate syntax form when your keys are always symbols. Instead of
options = { :font_size => 10, :font_family => "Arial" }
You could write it as:
options = { font_size: 10, font_family: "Arial" }
Now in your example #defeat = {r: :s, p: :r, s: :p}, all keys are symbol. That's why your example Hash is a valid construct, which has been introduced since 1.9.
When you use the hash style {key: value} you're actually declaring a symbol for the key. Like Arup's example, {:key => value} is the same thing with the implicit form. So anytime you use : instead of => in a hash, you are creating a symbol as the key.
In your example, you're creating symbols for both your key and your value.
{key: :value } # both are symbols

How do I create a hash from a querystring in ruby? [duplicate]

This question already has answers here:
Parse a string as if it were a querystring in Ruby on Rails
(5 answers)
Closed 9 years ago.
I want to create a hash from a querystring. This is my method:
def qs2h(querystring)
hashes = querystring.split('&').inject({}) do |result,query|
k,v = query.split('=')
if !v.nil?
result.merge(k.to_sym => v)
elsif !result.key?(k)
result.merge(k.to_sym => true)
else
result
end
end
hashes
end
qs2h('a=1&b=2&c=3&d') #=> {:a => "1", :b => "2", :c => "3", :d => true}
Is there any simpler method to do this in ruby?
Use CGI::parse:
CGI.parse('a=1&b=2&c=3&d')
# => {"a"=>["1"], "b"=>["2"], "c"=>["3"], "d"=>[]}
Hash[CGI.parse('a=1&b=2&c=3&d').map {|key,values| [key.to_sym, values[0]||true]}]
# => {:a=>"1", :b=>"2", :c=>"3", :d=>true}

Access nested hash element specified by an array of keys [duplicate]

This question already has answers here:
ruby use array tvalues to index nested hash of hash [duplicate]
(4 answers)
Map array of ints to nested array access
(2 answers)
Closed 8 years ago.
I'm trying to get a general solution to the problem of accessing an element in a nested hash given an array of key values,e.g.:
hash = { "a" => { "b" => 'foo' }}
array = ["a", "b"]
function(array)
=> "foo"
I'm guessing this could be a one-liner. It also is quite closely related to this problem:
Ruby convert array to nested hash
hash = { "a" => { "b" => 'foo' }}
array = ["a", "b"]
array.inject(hash,:fetch)
# => "foo"
array.inject(hash,:[])
# => "foo"

Resources