Как да клонирате масив в JavaScript

JavaScript има много начини да направи нещо. Написал съм на 10 начина за писане на пип / композиране в JavaScript и сега правим масиви.

1. Оператор за разпространение (плитко копие)

Откакто ES6 падна, това е най-популярният метод. Това е кратък синтаксис и ще го намерите изключително полезен, когато използвате библиотеки като React и Redux.

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

Забележка: Това не копира безопасно многомерни масиви. Стойностите на масива / обекта се копират по препратка вместо по стойност .

Това е добре

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. Добър стар за () цикъл (плитко копие)

Предполагам, че този подход е най- малко популярен, като се има предвид как модерното функционално програмиране се превърна в нашите среди.

Чист или нечист, декларативен или императивен, той свършва работата!

numbers = [1, 2, 3]; numbersCopy = []; for (i = 0; i < numbers.length; i++) { numbersCopy[i] = numbers[i]; } 

Забележка: Това не копира безопасно многомерни масиви. Тъй като използвате =оператора, той ще присвоява обекти / масиви по препратка вместо по стойност .

Това е добре

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. Добър стар докато () Цикъл (плитко копие)

Същото като — forнечисто, императивно, бла, бла, бла ... работи! ?

numbers = [1, 2, 3]; numbersCopy = []; i = -1; while (++i < numbers.length) { numbersCopy[i] = numbers[i]; } 

Забележка: Това също присвоява обекти / масиви по препратка вместо по стойност .

Това е добре

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 (плитко копие)

Обратно в съвременната територия ще намерим mapфункцията. Вкоренена в математиката, mapе концепцията за трансформиране на множество в друг тип множество, като същевременно се запазва структурата.

На английски това означава, че Array.mapвръща масив със същата дължина всеки път.

За да удвоите списък с числа, използвайте mapс doubleфункция.

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

Ами клонирането ??

Вярно е, че тази статия е за клониране на масиви. За да дублирате масив, просто върнете елемента във вашето mapобаждане.

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

Ако искате да бъдете малко по-математически, (x) => xсе нарича идентичност . Връща какъвто и да е параметър.

map(identity) клонира списък.

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

Забележка: Това също присвоява обекти / масиви по препратка вместо по стойност .

5. Array.filter (плитко копие)

Тази функция връща масив, точно както map, но не е гарантирано, че е със същата дължина.

Ами ако филтрирате за четни числа?

[1, 2, 3].filter((x) => x % 2 === 0); // [2] 

Дължината на входния масив беше 3, но получената дължина е 1.

Ако filterпредикатът на вашия файл винаги се връща true, получавате дубликат!

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

Всеки елемент преминава теста, така че се връща.

Забележка: Това също присвоява обекти / масиви по препратка вместо по стойност .

6. Array.reduce (плитко копие)

Почти се чувствам зле с reduceклонирането на масив, защото е много по-мощен от това. Но ето ...

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

reduce преобразува първоначална стойност, докато се придвижва през списък.

Тук първоначалната стойност е празен масив и ние го попълваме с всеки елемент, докато вървим. Този масив трябва да бъде върнат от функцията, за да се използва в следващата итерация.

Забележка: Това също присвоява обекти / масиви по препратка вместо по стойност .

7. Array.slice (плитко копие)

sliceвръща плитко копие на масив въз основа на предоставения от вас начален / краен индекс.

Ако искаме първите 3 елемента:

[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 onesafely 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

Well, this was fun ?

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