Franz
Franz

Reputation: 154

Ruby hash iteration, index access and value mapping

I have a hash with values paired to array-type values like so:

someHash={:key1=>[element1a,element1b],:key2=>[element2a,element2b]}

I tried to iterate over the Hash, access indices and modifying the Hash's array-type values like so:

hash.each_with_index{|(key,array),index|
    element1,element2 = array
    element1 = "new value"; element2="new value2"
}
hash

However, when I return the hash, the update has not occurred. Is there a hash method like the map! method for arrays I can use (or a different workaround)?

Upvotes: 0

Views: 1308

Answers (4)

spickermann
spickermann

Reputation: 106952

Your code just assigns values to some local variables. You need to assign the new values to the hash itself:

hash.each_with_index do |(key, array), index|
  element1, element2 = array
  element1 = "new value"
  element2 = "new value2"
  hash[key] = [element1, element2]
end

Or shorter (depending on what you try to achieve):

hash.each do |key, array|
  hash[key] = ["new value", "new value2"]
end

Or:

hash.update(hash) do |key, array|
  ["new value", "new value2"]
end

Upvotes: 2

davidrac
davidrac

Reputation: 10738

The problem in your code is that you are only changing the local references and not the values in the array.

You can use map like that:

new_hash = Hash[hash.map{|k,v| [k, ["new value","new value2"]]}]

This won't change the original hash.

Upvotes: 0

baron816
baron816

Reputation: 701

You don't need each_with_index. In fact, each_with_index doesn't exist for hash (the key is the index). You can just do this:

some_hash.each do |key, value|
    value[0], value[1] = "new value", "new value2"
end

Upvotes: 0

Johan S
Johan S

Reputation: 3591

When you do this:

element1, element2 = array

You are creating pointers to the elements in the array. When you later do this:

element1 = "new value"; element2="new value2"

You are settings those pointers to point to the new values, hence not modifying the initial array.

One solution is:

hash.each_with_index do |(key,array),index|
    array[0] = "new_value"
    array[1] = "new value2"
end

hash

I would however do something like this instead:

hash.each do |key, array|
    array[0] = "new_value"
    array[1] = "new value2"
end

hash

Upvotes: 0

Related Questions