Copy an Array with the Spread Operator (do not know how to turn logic into code)


function copyMachine(arr, num) {
  let newArr = [];
  while (num >= 1) {
    // change code below this line
    
    // change code above this line
    num--;
  }
  return newArr;
}

// change code here to test different cases:
console.log(copyMachine([true, false, true], 2));

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-data-structures/copy-an-array-with-the-spread-operator/

Okay, I kind of understand the purpose of this challenge and here are the things I think we need to achieve, but I have no idea how to turn it into code.

  • the num is how many times we need to add in arr
  • somehow we need to use newArr=[...arr]
  • (maybe??) we need to use methods like: push() or unshift()???

I am kind of lost.

1 Like

You understand everything perfectly! In your bullet list you mention everything that needs to be done, in some order, but maybe not the “exact” syntax you state.

Remember that newArr should contain the results noted in the tests that are listed. Look carefully at how the expected result is structured and you should be able to sort it out. Post a solution attempt if you still cant get it and we’ll see if we can push you further along.

think of it like you’re standing in front of a copy machine with a 3-page document. you want to make num copies of the document (the document is arr). when the copy machine is done making copies, you will have num copies of the original document. (that’s newArr)

so you want to add a copy of arr to newArr as many times as num tells you too. the spread operator (…) makes a copy of an array. and you were on the right track, push adds things to an array.

i hope that helps, it was really hard trying to think of how to help you without just giving you the answer!

2 Likes

okay. I am a bit loss when I see this part :

while(num>=1){
... //some code I need to write

num--;
}
  • why do we need to num--?

also I thought of 2 things that could be the solution, but I dont know which is which.

  1. newArr=newArr.push([...arr]); cos we need to push the identical arr using [...arr] to the newArr

  2. newArr=arr.push([...arr]); cos you gonna push the new elements into arr instead of the empty array.

I think one of the logic must be wrong… also if I key in the 1st one into console it tells me:

VM200:5 Uncaught TypeError: newArr.push is not a function

could you explain why??

oh wait… I think I understand the num-- part…

we push in one value then the num decrease by one, until one point the num has a value of 0.

is this correct???

  • the while loop runs as long as num is greater than or equal to 1. num-- decrements num so that the while loop doesn’t turn into an infinite loop.

  • newArr=newArr.push([…arr]); this is alllllmost right…(you don’t actually need to do any variable assignment in your solution)

1 Like

got it.

function copyMachine(arr, num) {
  let newArr = [];
  while (num >= 1) {
    // change code below this line
newArr.push(...[arr]);
    // change code above this line
    num--;
  }
  return newArr;
}

// change code here to test different cases:
console.log(copyMachine([true, false, true], 2));

yeah I remembered .push() will give you the number of elements of the new array you created.
so I just let it do it job, and went back to the original and it will be good. aka return newArr.

is this correct?

2 Likes

The problem with newArr = newArr.push([...arr]) is because the push() method doensn’t actually return an array—it’s return value is the length of the array, so assigning the result to newArr the first time is assigning the value 1 to newArr.

It is worth noting that the instructions are (I think) deliberately vague in order to avoid giving you the answer (but I personally think that it’s unnecessarily vague).

The whole point of copying an array is that you won’t mutate it if you perform mutating operations, like push on its copy. For example, consider this:

let arr = [1, 2, 3];
let brr = arr;

arr.unshift(0);

arr; // [0, 1, 2, 3]
brr; // [0, 1, 2, 3]
let arr = [1, 2, 3];
let brr = arr.slice();

arr.unshift(0);

arr; // [0, 1, 2, 3]
brr; // [1, 2, 3]

And the ... spread operator also lets you copy the whole array:

let arr = [1, 2, 3];
let brr = [...arr];

arr.unshift(0);

arr; // [0, 1, 2, 3]
brr; // [1, 2, 3]

But there is more to the spread operator, consider this example:

let arr = [0, 1, 2];
let brr = [3, 4];
let crr = [...arr, ...brr];
let drr = [...brr, ...arr];

arr; // [0, 1, 2]
brr; // [3, 4]
crr; // [0, 1, 2, 3, 4]
drr; // [3, 4, 0, 1, 2]

In the example above, you are decomposing the elements of the array, and putting them back in order. And the thing to note here is that push() is not necessary in this case. The whole point of this spread operator exercise is that you can use something that syntactically simpler to achieve the same result as push.

Since you have also just posted your solution (please blur it), it is worth noting that there is a solution that involves only the spread operator and doesn’t require push.

I hope that helps!

2 Likes

wait what? i just spent the last 10 minutes trying to figure out how you would accomplish this without using push or unshift.

also, the instructions say: “hint: another method we have already covered might come in handy here!” which i interpret as implicitly telling you to use push or unshift.

I highly recommend trying to figure it out yourself, because it will help you use the spread operator in more complex situations. You can do it like this:

newArr = [...newArr, [...arr]];

EDIT: Oh, I agree with you about the hint, but what I mean is that ideally it would make more sense, as practice, to not use push(). :slight_smile:

1 Like

:woman_facepalming: thanks!

1 Like

spoiler tag does not work when in code format…

this is a test

[spoiler]```
this is a test

okay… about this. the snippet below gives me the answer that I anticipated:

var a = [1,2];
var b = a.push(...a);
console.log(a);   // [1,2,1,2]
console.log(b);  //4

but why does this return 5??

function copyMachine(arr, num) {
  let newArr = [];
  while (num >= 1) {
    newArr = arr.push([...arr]);
    num--;
  }
  return newArr;
}

console.log(copyMachine([true, false, true], 2));

from my understanding, arr will be added two times after the original arr, which should be something like this? [true, false, true, true, false, true, true, false, true]? then why is the answer 5?

when you do
newArr = arr.push([...arr]);
arr now looks like [true, false, true, [true, false, true], [true, false, true]]
so arr.length is 5
if you do
newArr = arr.push(...arr);
then you get
[true, false, true, true, false, true, true, false, true]
and arr.length will be 9

1 Like

thanks !!! (20 character thingy)

let arr = [1, 2, 3];
let brr = arr;

arr.unshift(0);

arr; // [0, 1, 2, 3]
brr; // [0, 1, 2, 3]
let arr = [1, 2, 3];
let brr = arr.slice();

arr.unshift(0);

arr; // [0, 1, 2, 3]
brr; // [1, 2, 3]

let arr = [1, 2, 3];
let brr = [...arr];

arr.unshift(0);

arr; // [0, 1, 2, 3]
brr; // [1, 2, 3]

does this has something to do with passing by value VS passing by reference?
I read about it in YDKJS, but haven’t grasped it 100%.

oh… i see thanks!!!