v = { "foo"=>"bar"}
v["foo"] // bar
Say,
k = {:bar => 1}
>k[:bar] // 1
But,
k[v["foo"]] // nil
how to access key ==> value ( k[ key ] = value ) from hashes using a variable, say v["foo"]
You'll need to run to_sym on the result of v["foo"] in order to the the value in k:
1.9.3p484 :007 > v = { "foo"=>"bar"}
=> {"foo"=>"bar"}
1.9.3p484 :008 > k = {:bar => 1}
=> {:bar=>1}
1.9.3p484 :009 > k[v["foo"].to_sym]
=> 1
Related
Assume we have
hash = { a: 1, b: 2 }
hash2 = hash.to_hash
when I change value in hash2 it affect value in hash
hash2[:a] = 5
# hash[:a] = 5
Why ruby acts like that ?
How to fix this ?
Calling to_hash on a Hash returns itself. hash and hash2 are the same object.
2.6.5 :001 > hash = { a: 1, b: 2 }
=> {:a=>1, :b=>2}
2.6.5 :002 > hash2 = hash.to_hash
=> {:a=>1, :b=>2}
2.6.5 :003 > hash.object_id
=> 70244375263800
2.6.5 :004 > hash2.object_id
=> 70244375263800
I'm using Ruby 2.4. I'm confused about the whole reference vs value thing when copying the contents of a hash. How do I copy the contents of one hash into another without changing the reference (memory address?) of the hash? Below is the example of the problem I'm having ....
2.4.0 :003 > def copy_hash(h)
2.4.0 :004?> new_hash = {"a" => 1}
2.4.0 :005?> h = new_hash
2.4.0 :006?> end
=> :copy_hash
2.4.0 :007 > h = {"b" => 2}
=> {"b"=>2}
2.4.0 :008 > copy_hash(h)
=> {"a"=>1}
2.4.0 :009 > h
=> {"b"=>2}
In the function, I'm assigning the parameter to a new hash ...
h = new_hash
But once the function returns the original hash is unchanged. What's the right way to change the hash in the function so that when it returns the value of the parameter is also changed? That is, if my hash started out as
{"b" => 2}
I'd like the value to be
{"a"=>1}
after I invoke the "copy_hash" function.
You can use Hash#replace to replace the contents of the hash:
def copy(h)
new_hash = { 'a' => 1 }
h.replace(new_hash)
end
h = { 'b' => 2 }
copy(h)
h == { 'a' => 1 } # => true
I'm using Ruby 2.0 for a Rails project and am having some issues obtaining the element length of an array in the console.
First example
2.0.0-p353 :001 > search = "test"
=> "test"
2.0.0-p353 :002 > search.split
=> ["test"]
2.0.0-p353 :003 > search.length
=> 4
Second example
2.0.0-p353 :001 > search = "testOne, TestTwo"
=> "testOne, TestTwo"
2.0.0-p353 :002 > search.split(/[\s,]+/)
=> ["testOne", "TestTwo"]
2.0.0-p353 :003 > search.length
=> 16
How do I return the element count instead of the character count?
Well, you're not assigning your split array that's why you're seeing the discrepancy.
What you're actually doing is defining a string search and then trying to manipulate that same string.
Try this
testArray = search.split
testArray.size
>> 1
In the first example you are getting the length of the "test" string, not of the ["test"] array. You should assign it to a variable first.
i.e.:
search = "test" # => "test"
array = search.split # => ["test"]
array.length # => 1
I've the following Hash (dummy{}) with one member being an array, how do I build a code logic to:
(a) evaluate each Key -> Value
(b) evaluate each Key -> values(s) (if it is an array inside a Hash)
dummy = { :a1 => "xyz",
:b1 => ["xyz1", "ayz2", "xyz3", "xyz4"] }
The code I've for a Key with just one value is:
eval(dummy)[a1.to_sym]
I need a clean way to evaluate a hash member that has multiple values in an array.
Here is the IRB output:
1.9.3-p327 :002 > dummy = { :a1 => "xyz",
1.9.3-p327 :003 > :b1 => ["xyz1", "ayz2", "xyz3", "xyz4"] }
=> {:a1=>"xyz", :b1=>["xyz1", "ayz2", "xyz3", "xyz4"]}
Now I can access the members and their Key-Value pairs (in a very simple way as below:)
1.9.3-p327 :005 > pp dummy[:a1.to_sym]
"xyz"
=> "xyz"
1.9.3-p327 :006 > pp dummy[:b1.to_sym][0]
"xyz1"
=> "xyz1"
1.9.3-p327 :007 > pp dummy[:b1.to_sym][1]
"ayz2"
=> "ayz2"
1.9.3-p327 :008 > pp dummy[:b1.to_sym][2]
"xyz3"
=> "xyz3"
1.9.3-p327 :009 > pp dummy[:b1.to_sym][3]
"xyz4"
=> "xyz4"
Now, I need a "generic" ruby code that takes care of both the above situations to access the members and their values - note: for example, I only selected 1 and 4 values, but in reality my need is where the values range from 1000 - 5000
Making sure everything is an Array allows for uniform treatment:
dummy = { :a1 => "xyz",
:b1 => ["xyz1", "ayz2", "xyz3", "xyz4"] }
dummy.each do |k, v|
Array(v).each do |element| #Array(v) puts v in an Array, unless it already is an array.
puts element
end
puts
end
I don't understand how Ruby hashes work.
I expect these:
a = 'a'
{a => 1}[a] # => 1
{a: 1}[:a] # => 1
{2 => 1}[2] # => 1
How does this work?
{'a' => 1}['a'] # => 1
The first string 'a' is not the same object as the second string 'a'.
Ruby doesn't use object equality (equal?) for comparing hash keys. It wouldn't be very useful if it did after all.
Instead it uses eql?, which for strings is the same as ==
As a footnote to other answers, you can let a hash behave like you expected:
h = {'a'=> 1}
p h['a'] #=> 1
h.compare_by_identity
p h['a'] #=> nil ; not the same object
some_hash[k] = v
Basically, when you do this, what is stored is not a direct association k => v. Instead of that, k is asked for a hash code, which is then used to map to v.
Equal values yield equal hash codes. That's why your last example works the way it does.
A couple of examples:
1.9.3p0 :001 > s = 'string'
=> "string"
1.9.3p0 :002 > 'string'.hash
=> -895223107629439507
1.9.3p0 :003 > 'string'.hash == s.hash
=> true
1.9.3p0 :004 > 2.hash
=> 2271355725836199018
1.9.3p0 :005 > nil.hash
=> 2199521878082658865