0

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)?

1
  • Welcome to Stack Overflow. Your variable is called someHash. Your code never references that variable. In Ruby we use snake_case for variables and classes, not camelCase, so use some_hash, but a more mnemonic name for the variable would be good. The methods available to enumerables are well documented. Please search those first as this question could easily be answered by reading the documentation. Commented Oct 31, 2015 at 20:38

4 Answers 4

2

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
Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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

2 Comments

Have you forgotten that, since v1.9, a hash's key insertion order is maintained? There are many applications that make use of that property, so it wouldn't be surprising if one wanted the hash's ith key-value pair (though it's not relevant here). Incidentally, many old-school coders have never accepted the concept of an ordered hash.
Oh, yeah I keep looking at the 1.9.3 docs. It's what always comes up for me in a google search.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.