Array.join() can't change the items' value in an array. But it does here... Why?

Array.join() can't change the items' value in an array. But it does here... Why?
0

#1

First of all - here be spoilers for the “No repeats please” assignment. Part of my solution is visible below, so if you haven’t done it yet you might want to stop reading.

I’ve written the following code for creating an array with all possible permutations of a given string (it’s Heap’s permutation algorithm).

It works as expected, so if I evoke it with permAlone(‘abc’); the output is:
[“acb”, “bac”, “cab”, “acb”, “bca”, “cba”]

The thing that I thoroughly don’t understand (and that made me search blindly for what was wrong with my code) is this:

What array.join() does is it takes all elements of an array and joins them into one string. So if I omit it from the code above, and write
permArr.push(strArr);
instead of
permArr.push(strArr.join(""));
I should get the same letters, in the same sequence - but each item in permArr should be a nested array of single letters instead of a string of letters. Right?

Apparently not, because without the .join the output is:
[[“a”,“b”,“c”],[“a”,“b”,“c”],[“a”,“b”,“c”],[“a”,“b”,“c”],[“a”,“b”,“c”],[“a”,“b”,“c”]]

I don’t even know how to begin searching for an explanation of this. Could somebody point me in the right direction?


#3

For some reason one line of the code was not displayed in the post (searching now why). But I am sure about the rest - posted img from the whole assignment.


#4

THANK YOU! I was doubting my sanity until I stumbled upon this post.

I noticed this exact situation as well. I originally did not have the .join('') on my array when I was pushing it to my array of permutations and kept getting the [[a,b,c],[a,b,c]... result. I assumed my code wasn’t working and figured it had to be due to some scope issue with recursion that I didn’t understand. After hours of troubleshooting, I finally stumbled upon another student’s code and realized the only difference between their working solution and mine was that they included the .join('') before pushing to their results. I tried including it, and sure enough my code now works.

The silver lining here for me is that I learned a lot about JavaScript scope, recursion, passing by reference/value, etc., however, I still have absolutely no idea what is going on with this. Why would joining the array into a string change the value of what is being pushed?

Any ideas anyone?


#5

I don’t quite get what you mean by the value had changed.
That is the correct output if you don’t use join.

Array.push( “a” ); pushes a single element into the array.
Array.push( [a,b,c] ); pushes the whole array into one single element.
Array.push( [a,b,c].join( “” ) ); pushes the result of joining abcd into one element.


#6

Okay, I think I have this figured out now.

From what I’m understanding, I guess this does have to do with passing by value/reference.

Here is a quick article on the subject:

And here is an article explaining how arrays in javascript are passed by reference:

To summarize, without the .join(’’) you are pushing a reference to the individual array (strArr) to your array of permutations (permArr). So then really your permArr array is just an array containing 6 references to permArr. At the time your permArr is returned to display your final results, it is displaying 6 references to strArr, which at that time is equal to [“a”, “b”, “c”].

However, with the .join(’’), you are actually passing the value of the joined array, which is a string. Strings, as the previous articles state, are passed by value. So by adding the .join(’’) method you are filling up your permArr array with 6 string values. You can think of these 6 string values as being “string-snapshots” that capture the current state of the strArr array as a string value at the time of the push.

I tried to play with this a little to learn more. Let’s say you in fact wanted your final permutations as arrays and not strings. Simply adding .slice(0) to the end of strArr before pushing it to permArr would do the trick. I believe this is because the .slice() method of an array returns a copy of the value of the array, and not a reference to the original array.

Does this make sense? And everyone should feel free to call me out if anything I’ve said here is not correct.

Here are some additional articles that helped me understand this: