Hvordan klone en matrise i JavaScript

JavaScript har mange måter å gjøre hva som helst. Jeg har skrevet på 10 måter å skrive rør / komponere i JavaScript, og nå gjør vi arrays.

1. Spread Operator (Grunn kopi)

Helt siden ES6 falt, har dette vært den mest populære metoden. Det er en kort syntaks, og du vil finne det utrolig nyttig når du bruker biblioteker som React og Redux.

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

Merk: Dette kopierer ikke flerdimensjonale matriser trygt. Array / objektverdier kopieres ved referanse i stedet for etter verdi .

Dette er greit

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

Dette er ikke greit

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 (Grunn kopi)

Jeg forestiller meg at denne tilnærmingen er minst populær, gitt hvordan trendy funksjonell programmering blir i våre kretser.

Ren eller uren, erklærende eller viktig, det gjør jobben!

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

Merk: Dette kopierer ikke flerdimensjonale matriser trygt. Siden du bruker =operatøren, vil den tildele objekter / matriser med referanse i stedet for etter verdi .

Dette er greit

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

Dette er ikke greit

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. God gammel mens () sløyfe (grunne kopi)

Samme som for—impure, imperativ, bla, bla, bla ... det fungerer! ?

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

Merk: Dette tildeler også objekter / matriser ved referanse i stedet for etter verdi .

Dette er greit

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

Dette er ikke greit

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 (Grunn kopi)

Tilbake i moderne territorium finner vi mapfunksjonen. Forankret i matematikk, maper begrepet å transformere et sett til en annen type sett, samtidig som strukturen bevares.

På engelsk betyr det at du Array.mapreturnerer en matrise med samme lengde hver eneste gang.

For å doble en liste med tall, bruk mapmed en doublefunksjon.

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

Hva med kloning ??

Det er sant at denne artikkelen handler om kloning av matriser. For å duplisere en matrise, er det bare å returnere elementet i mapsamtalen din .

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

Hvis du vil være litt mer matematisk, (x) => xkalles identitet . Den returnerer hvilken parameter den har blitt gitt.

map(identity) kloner en liste.

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

Merk: Dette tildeler også objekter / matriser ved referanse i stedet for etter verdi .

5. Array.filter (grunne kopi)

Denne funksjonen returnerer en matrise, akkurat som map, men den er garantert ikke like lang.

Hva om du filtrerer etter partall?

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

Inndatamatlengden var 3, men den resulterende lengden er 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 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)

Dette kan gjøre ethvert iterabelt objekt til en matrise. Å gi en matrise returnerer en grunne kopi.

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

Merk: Dette tildeler også objekter / matriser ved referanse i stedet for etter verdi .

Konklusjon

Vel, dette var gøy?

Jeg prøvde å klone med bare ett trinn. Du finner mange flere måter hvis du bruker flere metoder og teknikker.