Javascript copy and array

# ES6 Way to Clone an Array 🐑

Because arrays in JS are reference values, so when you try to copy it using the = it will only copy the reference to the original array and not the value of the array. To create a real copy of an array, you need to copy over the value of the array under a new value variable. That way this new array does not reference to the old array address in memory.

const sheeps = ['🐑', '🐑', '🐑']; const fakeSheeps = sheeps; const cloneSheeps = [. sheeps]; console.log(sheeps === fakeSheeps); // true --> it's pointing to the same memory space console.log(sheeps === cloneSheeps); // false --> it's pointing to a new memory space 

# Problem with Reference Values

If you ever dealt with Redux or any state management framework. You will know immutability is super important. Let me briefly explain. An immutable object is an object where the state can’t be modified after it is created. The problem with JavaScript is that arrays are mutable. So this can happen:

const sheeps = ['🐑', '🐑']; const sheeps2 = sheeps; sheeps2.push('🐺'); console.log(sheeps2); // [ '🐑', '🐑', '🐺' ] // Ahhh 😱 , our original sheeps have changed?! console.log(sheeps); // [ '🐑', '🐑', '🐺' ] 

That’s why we need to clone an array:

const sheeps = ['🐑', '🐑']; const sheeps2 = [. sheeps]; // Let's change our sheeps2 array sheeps2.push('🐺'); console.log(sheeps2); // [ '🐑', '🐑', '🐺' ] // ✅ Yay, our original sheeps is not affected! console.log(sheeps); // [ '🐑', '🐑' ] 

# Mutable vs Immutable Data Types

All primitives are immutable.

Читайте также:  Dynamic Scaling Example

# Shallow Copy Only

Please note spread only goes one level deep when copying an array. So if you’re trying to copy a multi-dimensional arrays, you will have to use other alternatives.

const nums = [[1, 2], [10]]; const cloneNums = [. nums]; // Let's change the first item in the first nested item in our cloned array. cloneNums[0][0] = '👻'; console.log(cloneNums); // [ [ '👻', 2 ], [ 10 ], [ 300 ] ] // NOOooo, the original is also affected console.log(nums); // [ [ '👻', 2 ], [ 10 ], [ 300 ] ] 

🤓 Here’s an interesting thing I learned. Shallow copy means the first level is copied, deeper levels are referenced.

# Community Input

# Array.from is Another Way to Clone Array

const sheeps = ['🐑', '🐑', '🐑']; const cloneSheeps = Array.from(sheeps); 

Источник

How to clone an array in JavaScript

Yazeed Bzadough

Yazeed Bzadough

How to clone an array in JavaScript

JavaScript has many ways to do anything. I’ve written on 10 Ways to Write pipe/compose in JavaScript, and now we’re doing arrays.

Here’s an interactive scrim that shows various ways to clone arrays in JavaScript:

1. Spread Operator (Shallow copy)

Ever since ES6 dropped, this has been the most popular method. It’s a brief syntax and you’ll find it incredibly useful when using libraries like React and Redux.

numbers = [1, 2, 3]; numbersCopy = [. numbers]; 

Note: This doesn’t safely copy multi-dimensional arrays. Array/object values are copied by reference instead of by value.

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 
nestedNumbers = [[1], [2]]; numbersCopy = [. nestedNumbers]; numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

2. Good Old for() Loop (Shallow copy)

I imagine this approach is the least popular, given how trendy functional programming’s become in our circles.

Pure or impure, declarative or imperative, it gets the job done!

numbers = [1, 2, 3]; numbersCopy = []; for (i = 0; i

Note: This doesn’t safely copy multi-dimensional arrays. Since you’re using the = operator, it’ll assign objects/arrays by reference instead of by value.

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 
nestedNumbers = [[1], [2]]; numbersCopy = []; for (i = 0; i < nestedNumbers.length; i++) < numbersCopy[i] = nestedNumbers[i]; >numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

3. Good Old while() Loop (Shallow copy)

Same as for —impure, imperative, blah, blah, blah…it works! ?

numbers = [1, 2, 3]; numbersCopy = []; i = -1; while (++i

Note: This also assigns objects/arrays by reference instead of by value.

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 
nestedNumbers = [[1], [2]]; numbersCopy = []; i = -1; while (++i < nestedNumbers.length) < numbersCopy[i] = nestedNumbers[i]; >numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

4. Array.map (Shallow copy)

Back in modern territory, we’ll find the map function. Rooted in mathematics, map is the concept of transforming a set into another type of set, while preserving structure.

In English, that means Array.map returns an array of the same length every single time.

To double a list of numbers, use map with a double function.

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

What about cloning??

True, this article’s about cloning arrays. To duplicate an array, just return the element in your map call.

numbers = [1, 2, 3]; numbersCopy = numbers.map((x) => x); 

If you’d like to be a bit more mathematical, (x) => x is called identity. It returns whatever parameter it’s been given.

map(identity) clones a list.

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

Note: This also assigns objects/arrays by reference instead of by value.

5. Array.filter (Shallow copy)

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

What if you’re filtering for even numbers?

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!

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

Every element passes the test, so it gets returned.

Note: This also assigns objects/arrays by reference instead of by value.

6. Array.reduce (Shallow copy)

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

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

reduce transforms an initial value as it loops through a list.

Here the initial value is an empty array, and we’re filling it with each element as we go. That array must be returned from the function to be used in the next iteration.

Note: This also assigns objects/arrays by reference instead of by value.

7. Array.slice (Shallow copy)

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

If we want the first 3 elements:

[1, 2, 3, 4, 5].slice(0, 3); // [1, 2, 3] // Starts at index 0, stops at index 3 

If we want all the elements, don’t give any parameters

numbers = [1, 2, 3, 4, 5]; numbersCopy = numbers.slice(); // [1, 2, 3, 4, 5] 

Note: This is a shallow copy, so it also assigns objects/arrays by reference instead of by value.

8. JSON.parse and JSON.stringify (Deep copy)

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.

Note: This one safely copies deeply nested objects/arrays!

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

9. Array.concat (Shallow copy)

concat combines arrays with values or other arrays.

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

If you give nothing or an empty array, a shallow copy’s returned.

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

Note: This also assigns objects/arrays by reference instead of by value.

10. Array.from (Shallow copy)

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

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

Note: This also assigns objects/arrays by reference instead of by value.

Conclusion

I tried to clone using just 1 step. You’ll find many more ways if you employ multiple methods and techniques.

Источник

How to copy an array in JavaScript

Since arrays are collection-like objects in JavaScript, you can not simply use the equal operator ( = ) to copy the values. It will only copy the reference to the original object and not the elements of the array.

In vanilla JavaScript, there are multiple ways to clone the contents of an array. You can either use the Array.slice() method, the Array.from() method, or the spread operator ( . ) to duplicate an array. You don’t need to use a loop to iterate over all elements of an array and push them into another array.

Note: If you want to create a deep clone of an array, take a look at this article.

The simplest and quickest way to copy the contents of an existing array into a new array is by using the slice() method without any parameter:

const fruits = ['🍑', '🍓', '🍉', '🍇', '🍒']; // clone `fruits` using `slice()` const moreFruits = fruits.slice(); console.log(moreFruits); // ['🍑', '🍓', '🍉', '🍇', '🍒'] 

In the above code, the slice() method creates a shallow copy of the original array, and not a deep clone. The original array remains unchanged. If the original array contains objects, only their references will be copied to the new array.

Another way to clone an array in JavaScript is by using the Array.from() method. It creates a new, shallow-copied Array object from an array-like or iterable object. Here is an example:

const fruits = ['🍑', '🍓', '🍉', '🍇', '🍒']; // clone `fruits` using `Array.from()` const moreFruits = Array.from(fruits); 

The Array.from() method was introduced in ES6, so it only works in modern browsers. But you can use a polyfill to push the browser support way back to IE6.

The spread operator ( . ) is another option available in modern JavaScript (ES6 and higher) that can be used to clone an array by «spreading» its elements:

const fruits = ['🍑', '🍓', '🍉', '🍇', '🍒']; // clone `fruits` using spread operator const moreFruits = [. fruits]; 

Just like Array.slice() , the spread operator creates a shallow copy of the original array. It only goes one-level down when cloning an array. If you’re coping multi-dimension array or an array that contains objects, you have to look for other alternatives.

Although the Array.concat() method is originally used for merging two arrays into one, you can use it for cloning an array as well:

const fruits = ['🍑', '🍓', '🍉', '🍇', '🍒']; // merge `fruits` with emtpy array to // create a new array const moreFruits = [].concat(fruits); 

Take a look at this guide to learn more about JavaScript arrays and how to use them to store multiple values in a single variable. ✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.

You might also like.

Источник

Оцените статью