ruby merge two hash by same key and same values [duplicate] - ruby

This question already has answers here:
How to merge Ruby hashes
(4 answers)
Closed 6 years ago.
Note: that the two hashes has the with same key and the same values
a = {:ip=>'192.168.2.1',:b=>2}
b = {:ip=>'192.168.2.1',:c=>4}
i want to merge them to a new hash like this
newhash= {:ip=>'192.168.2.1',:b=>2,:c=4}

Use Hash#merge
a = {:ip=>"192.168.2.1", :b=>2}
b = {:ip=>"192.168.2.1", :c=>4}
newhash = a.merge(b)
#=> {:ip=>"192.168.2.1", :b=>2, :c=>4}

Related

How to remove double quotes from ruby array [duplicate]

This question already has answers here:
Convert array of strings to an array of integers
(2 answers)
Closed 2 months ago.
I am facing an issue converting ruby array ["1", "2"] to [1,2]
we can use ["1", "2"].map{|n| eval n} but the use of eval is a serious security risk.
Any suggestions?
Just use:
["1", "2"].map(&:to_i)
#=> [1, 2]
Which is basically the same as
["1", "2"].map { |number| number.to_i }
See Array#map and String#to_i.

Return a default value of a hash [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I need help. I am doing a basic exercise in Ruby, but right now I don't understand defult that much.
I need to write a function called temp that reicive one argument (a hash). The function must return the same hash but with the next changes:
If the hash doesn't have the key :puppy return 4 as value.
If the hash doesn't have the key :cat return 6 as value.
Assuming this question is about default values, you're after either default or default_proc. You can make a new hash and give it a default proc via Hash.new.
def temp(h)
Hash.new do |hash, key|
if key == :puppy
h.fetch(:puppy, 4)
elsif key == :cat
h.fetch(:cat, 6)
else
h[key]
end
end
end
While Hash#default_proc is the right way to go, both answers here are overcomplicated for this particular task. The following is probably what you actually need here.
def temp(h)
h[:puppy] ||= 4
h[:cat] ||= 6
h
end
Your question is a little confusing.
If the hash doesn't have the key :puppy return 4 as value.
If the hash doesn't have the key :cat return 6 as value.
I think you want a function that returns a version of the passed-in hash that defaults the keys :puppy and :cat to 4 and 6, respectively, assuming they aren't already in the passed-in hash. This should work:
def temp(source)
return Hash.new do |h, k|
case k
when :puppy then 4
when :cat then 6
end
end.merge(source)
end
Here's how this works.
We're defining a method that takes as its one parameter a basis hash (which I called source).
When you create a hash with Hash.new and pass in a block of code, that block becomes the hash's "default proc". It will be called whenever a key that is not present in the hash is looked up, and its return value will appear to be the value stored at that key. When such a lookup happens, the block is passed two arguments: the hash itself and the key being requested. Here, I named those h and k. In the body, we check to see if k is either :puppy or :cat and return the appropriate value (4 or 6) if so. (If k is not either of those values, the case statement will automatically return nil.)
That creates a hash with the right default proc, but the hash is empty. We then populate it by calling Hash#merge on it with the passed-in source hash as argument; that will copy all of the keys from source into the new hash. The merge method call conveniently returns the hash it was called on, so we just return that result to the caller of our method.
Examples:
irb(main):001:0> h1 = temp( { a: 1, b: 2, c: 3 } )
=> {:a=>1, :b=>2, :c=>3}
irb(main):002:0> h1[:a]
=> 1
irb(main):003:0> h1[:d]
=> nil
irb(main):004:0> h1[:cat]
=> 6
irb(main):005:0> h1[:puppy]
=> 4
irb(main):006:0> h2 = temp( { a: 1, cat: :dog } )
=> {:a=>1, :cat=>:dog}
irb(main):007:0> h2[:a]
=> 1
irb(main):008:0> h2[:b]
=> nil
irb(main):009:0> h2[:cat]
=> :dog
irb(main):010:0> h2[:puppy]
=> 4

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"

Modifying a hash with multiple occurrences [duplicate]

This question already has answers here:
How do I copy a hash in Ruby?
(13 answers)
Closed 8 years ago.
a is a hash. s is an array where I want to push the hash a iteratively. The idea is to retain the value of each iteratively pushed hash independently. Here is what I tried.
a = {:a=> 1, :b=>2}
s = []
s << a
s << a # => [{:b=>2, :a=>1}, {:b=>2, :a=>1}]
a[:b] = 3
s # => [{:b=>3, :a=>1}, {:b=>3, :a=>1}]
t = []
t.push(a) # => [{:b=>3, :a=>1}]
t.push(a) # => [{:b=>3, :a=>1}, {:b=>3, :a=>1}]
a[:b] = 4
t # => [{:b=>4, :a=>1}, {:b=>4, :a=>1}]
The above doesn't give me the solution: Changing a changes the values in the elements inside the array which were previously pushed. After pushing a to s twice, I changed a[:b] from 2 to 3, and all the elements reflected the change. Suggestion for this please.
Use dup every time you're adding to s
s << a.dup
The dup method will create shallow copy of hash.
Update:
In case if the shallow copy doesn't satisfy the requirements, then use Marshaling
s << Marshal.load( Marshal.dump(a) )
Use
s << Hash[a]
This will copy the Hash and allow you to change the original.

Ruby's Unary * Operator [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the * operator doing to this string in Ruby
I ran across the following code when looking for an easy way to convert an array to a hash (similar to .Net's ToDictionary method on IEnumerable... I wanted to be able to arbitrarily set the key and the value).
a = [ 1, 2, 3, 4, 5, 6 ]
h = Hash[ *a.collect { |v| [ v, v ] }.flatten ]
My question is, what does the asterisk before a.collect do?
By the way, the code comes from http://justatheory.com/computers/programming/ruby/array_to_hash_one_liner.html
It's the splat-operator if you want to google it. It does transform an array into a list (so you can use an array as arguments to a method). It also does the opposite: it can 'slurp' a list into an array.
require 'date'
*date_stuff = 2012,2,29 # slurp
p date_stuff #=> [2012, 2, 29]
Date.new(*date_stuff) # regurgitate

Resources