Slice and Splice - arrays should remain the same conditions not met

Slice and Splice - arrays should remain the same conditions not met
0

#1

Can’t seem to pass the challenge because of these conditions:

The first array should remain the same after the function runs.
The second array should remain the same after the function runs.

I was careful to create arrays to process in order not to change the original input arrays.

My code so far


function frankenSplice(arr1, arr2, n) {

var arr4 = arr1.reverse();
var arr3 = arr2;

for (var i = 0; i < arr4.length; i++) {
  
arr3.splice(n, 0, arr4[i]);
}

return arr3;
}

frankenSplice([1, 2], ["a", "b"], 1);

This code gives me the same result:

function frankenSplice(arr1, arr2, n) {

var arr1 = arr1.reverse();

for (var i = 0; i < arr1.length; i++) {
  
arr2.splice(n, 0, arr1[i]);
}

return arr2;
}

frankenSplice([1, 2], ["a", "b"], 1);

I’m a bit at a loss, I’ve tried a few things but nothing comes as close to passing the challenge as this code since array.prototype.slice creates a nested array. I’m not sure there’s a clean way to make this happen other than this .

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-algorithm-scripting/slice-and-splice


#2

I did not read the code thoroughly, but from the looks of it you seem to believe that a statement like

var arr3 = arr2;

works for arrays (an any other objects) like it works for integers or strings. In fact, a statement like this does not copy the values of arr2 (arr2[0], arr2[1] and so on) in arr3 (the so called deep copy), but rather copies the reference to arr2. I won’t explain the difference here, but checkthis out. What does that mean? It means that when you change arr2, arr3 will be changed also, because they refer to the same object.

If you want to make a deep copy of arr2 in a new arrayarr3, use

var arr3 = arr2.slice();

In this arr3, changes to not affect arr2. Hope I’m not misconstruing your code.


#3

Cheers Dan,

This solved the issue as far as the second array is concerned. Now the issue with the first array remains.

But, if I follow what you’ve said, since I’ve applied a transformation to the first array in

var arr4 = arr1.reverse();

it should indeed create a value in arr4 and not just reference arr1, right?


#4

Sorry for the late reply, but I’ve been away for the weekend. If you want arr4 to be a reverse copy of arr1 without altering arr1, then use

var arr4 = arr1.slice().reverse();

The way you wrote it, arr1 gets reversed, too.

BTW, the slice trick only works if we’re talking about arrays of primitives. For arrays of objects it gets more complicated. You can use Object.assign or JSON.stringify to copy objects, but this can get complicated and Google is your friend in this case.


#5

@Dan_Cio Great tip, I’ll keep that in my back pocket from now on as I had the exact same issue.

Moral of the story - you can’t copy an array simply by creating another variable that references it directly.


#6

Thanks from me as well, Dan!

Think I more or less understand what is happening here - using slice without any parameters passed in results in the entire array being ‘sliced’ into a new array. I guess this is the only way to generate a copy of an array rather than creating the situation you described where it is simply the reference to the array you are attempting to copy.

No need to reply - just thinking out loud! Unless I’ve completely misunderstood of course :slight_smile:


#7

Instead of slice() you can use Array.from, which is a more modern approach to copying arrays. Here is a bit of code to show how it works:

let arr1 = [2, 4, 5];
let arr2 = arr1;
let copy = Array.from(arr1);
console.log(copy); // [2, 4, 5]
console.log(arr2); // [2, 4, 5]
console.log(arr1 === copy); //false
console.log(arr1 === arr2); //true

The fact that even if arr2 and copy have the same content but one is equal to arr1 (that would be arr2) while the other (i.e., copy) is not happens because equality between two objects is true if they share the same reference. In the case of arr1 and copy that is not the case, which shows that Array.from creates a new array, with the same content as the array in its argument.


#8

Very interesting - thanks for taking the time to clarify, Dan!