user1446375
user1446375

Reputation: 11

Array in value of hash

How to push inputs into a value of a hash? My problem is that I got multiple keys and all of them reference arrays.

{"A"=>["C"], "B"=>["E"], "C"=>["D"], "D"=>["B"]}

How can I push another String onto one of these? For example I want to add a "Z" to the array of key "A"?

Currently I either overwrite the former array or all data is in one.

Its about converting a Array ["AB3", "DC2", "FG4", "AC1", "AF4"] into a hash with {"A"=>["B", "C", "F"]}.

Upvotes: 1

Views: 176

Answers (3)

kiddorails
kiddorails

Reputation: 13014

Better approach:

Add a new class method in Hash as below:

class Hash
  def add (k,v)
    unless self.key?k
      self[k] = [v] 
    else
      self[k] = self[k] << v
    end 
    self
  end 
end


h={}
h.add('A','B') #=> {"A"=>["B"]}
h.add('A','C') #=> {"A"=>["B", "C"]}
h.add('B','X') #=> {"A"=>["B", "C"], "B"=>["X"]}

Done.

This can be even more idiomatic according to your precise problem; say, you want to send multiple values at once, then code can be DRY-ed to handle multiple arguments.

Hope this helps.

All the best.

Upvotes: 0

Michael Kohl
Michael Kohl

Reputation: 66867

You said your original problem is converting the array ["AB3", "DC2", "FG4", "AC1", "AF4"] into the hash {"A"=>["B", "C", "F"]}, which can be done like this:

Hash[a.group_by { |s| s[0] }.map { |k, v| [k, v.map { |s| s[1] }] }]

Or like this:

a.inject(Hash.new{|h, k| h[k]=[]}) { |h, s| h[s[0]] << s[1] ; h }

Note that Hash.new{|h, k| h[k]=[]} creates an array with a default value of [] (an empty array), so you'll always be able to use << to add elements to it.

Upvotes: 0

Yuri  Barbashov
Yuri Barbashov

Reputation: 5437

Any command <<, push, unshift will do a job

if h["A"] 
  h["A"] << "Z"
else
  h["A"] = ["Z"]
end

Upvotes: 1

Related Questions