So why is it that the original code (in comments) does not work?
When you use Hash.new([])
the default array for every key is the same array. It doesnât create separate empty arrays for each key. It gives them all the same instance. So when you add an item to that array, it adds it to every keyâs array because they all actually have the same array. +=
creates a new array instead of adding a new item to the existing array so it works fine.
Thanks Jeremiah.
I now understand that with Hash.new([]) the default object [] is shared by the various keys; no separate empty array per key.
However, I still canât figure out why the return value should be an empty hash.
- Within the each_with_index iterarator , the index for each key gets to be shoveled into the default [], so
- After the last iteration, shouldnât the âpositionsâ hash carry all unique keys pointing to the default array? (which contains the index of every element of the âselfâ array). Hope the question makes sense
Upon further thought, maybe this explanation holds. Will be great if peers/staff can help correct/cement the understanding of this subtlety.
-
The statement positions[item] << index never assigns/binds the default value (the default array object) to the key. Not for any key in self.
-
This is based on reading of This Post by Gary W.
Hash.new(x) returns x when a key isnât found. It will be the
same x for every key and wonât store x in the hash, just return
it on a key miss.
- In our case x is the default array.
- By using positions[item] << index , the lack of binding operation â=â, means the default array x will never be returned and in turn assigned to positions[item]
Edit: I wrote this without seeing your second post. Your understanding is correct.
When you call positions[item]
and the positions
hash doesnât have the key item
, it returns the default array. It does not add the key item
to the hash. It just returns the default array. So when you do
positions[item] << index
the code evaluates positions[item]
first. When it finds that the positions
hash doesnât contain the key item
, it just returns the default array without actually adding the key item
to the array. Next it evaluates
<< index
which just shoves index
into the default array. Again, nothing in this code has actually added the key item
to the positions
hash, and nothing as assigned it a new value.
x += y
is just shorthand for x = x + y
. So letâs look at the working version of the code in that format:
positions[item] = positions[item] + [index]
See the assignment in there? Thatâs the important difference. When you assign a value to a hashâs key, the hash creates that key and stores the new value. Thatâs what the other code is lacking. No new value is ever actually assigned to the hashâs key. So first the code evaluates the right side of the equal sign:
positions[item] + [index]
So positions[item]
returns the default array, but the it adds that array together with [index]
to create a new array. Then the code evaluates the assignment. It assigns the new array to positions[item]
.