Blog

Array

JS

How to copy an array

Interesting ways to clone/copy an array

Vignesh Kalithas

Vignesh Kalithas

Oct 10, 2022 — Updated Dec 8, 2022 · 4 min read

A shallow copy means that certain (sub-)values are still connected to the original variable.

  • The spread operator is a new addition to the features available in the JavaScript ES6 version
  • The spread operator ... is used to expand or spread an iterable or an array

_7
numbers = [1, 2, 3];
_7
numbersCopy = [...numbers];
_7
numbersCopy.push(4);
_7
_7
console.log(numbers); // [1, 2, 3]
_7
console.log(numbersCopy); // [1, 2, 3, 4]
_7
// numbers array is unaffected


_7
nestedNumbers = [[1], [2]];
_7
numbersCopy = [...nestedNumbers];
_7
_7
numbersCopy[0].push(300);
_7
console.log(nestedNumbers); // [[1, 300], [2]]
_7
console.log(numbersCopy); // [[1, 300], [2]]
_7
// Both have been changed because they share the same reference


_11
numbers = [1, 2, 3];
_11
numbersCopy = [];
_11
_11
for (i = 0; i < numbers.length; i++) {
_11
numbersCopy[i] = numbers[i];
_11
}
_11
_11
numbersCopy.push(4);
_11
console.log(numbers); // [1, 2, 3]
_11
console.log(numbersCopy); // [1, 2, 3, 4]
_11
// numbers array is unaffected

  • The map() method in JS creates an array by calling a specific function on each element present in the parent array. It is a non-mutating method.
  • Generally, map() method is used to iterate over an array and call a function on every element of the array.


_11
numbers = [1, 2, 3];
_11
double = (x) => x * 2;
_11
_11
numbers.map(double);
_11
_11
numbers = [1, 2, 3];
_11
numbersCopy = numbers.map((x) => x);
_11
_11
identity = (x) => x;
_11
numbers.map(identity);
_11
// [1, 2, 3]


_2
// What if you’re filtering for even numbers?
_2
[1, 2, 3].filter((x) => x % 2 === 0); // [2]

  • This function returns an array, just like map, but it’s not guaranteed to be the same length.

  • The input array length was 3, but the resulting length is 1.

  • If your filter's predicate always returns true, however, you get a duplicate!

  • Every element passes the test, so it gets returned.


_2
numbers = [1, 2, 3];
_2
numbersCopy = numbers.filter(() => true);

  • I almost feel bad using reduce to clone an array, because it’s so much more powerful than that. But here we go…

_6
numbers = [1, 2, 3];
_6
_6
numbersCopy = numbers.reduce((newArray, element) => {
_6
newArray.push(element);
_6
return newArray;
_6
}, []);

  • slice returns a shallow copy of an array based on the provided start/end index you provide.

_10
//If we want the first 3 elements:
_10
_10
[1, 2, 3, 4, 5].slice(0, 3);
_10
// [1, 2, 3]
_10
// Starts at index 0, stops at index 3
_10
If we want all the elements, don’t give any parameters
_10
_10
numbers = [1, 2, 3, 4, 5];
_10
numbersCopy = numbers.slice();
_10
// [1, 2, 3, 4, 5]


_2
[1, 2, 3].concat(4); // [1, 2, 3, 4]
_2
[1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5]

  • concat combines arrays with values or other arrays
  • If you give nothing or an empty array, a shallow copy’s returned

_2
[1, 2, 3].concat(); // [1, 2, 3]
_2
[1, 2, 3].concat([]); // [1, 2, 3]

This can turn any iterable object into an array. Giving an array returns a shallow copy.


_3
numbers = [1, 2, 3];
_3
numbersCopy = Array.from(numbers);
_3
// [1, 2, 3]

A deep copy means that all of the values of the new variable are copied and disconnected from the original variable

  • JSON.stringify() turns an object into a string.

  • JSON.parse() turns a string into an object.

  • Combining them can turn an object into a string, and then reverse the process to create a brand new data structure.


_7
nestedNumbers = [[1], [2]];
_7
numbersCopy = JSON.parse(JSON.stringify(nestedNumbers));
_7
_7
numbersCopy[0].push(300);
_7
// nestedNumbers -> [[1], [2]]
_7
// numbersCopy -> [[1, 300], [2]]
_7
// These two arrays are completely separate!

@ragavkumarv
swipe to next ➡️