Hakkerointi JavaScript-ryhmien luomiseen

Oivaltavia vinkkejä taulukkojen luomiseen ja kloonaamiseen JavaScript-muodossa.

Alkuperäinen kuva: Markus Spiske on Unsplash

Jokaisen ohjelmointikielen erittäin tärkeä osa on kielellä käytettävissä olevat tietotyypit ja rakenteet. Useimmat ohjelmointikielet tarjoavat tietotyyppejä monimutkaisten tietojen esittämiseksi ja käsittelemiseksi. Jos olet työskennellyt sellaisten kielten kanssa, kuten Python tai Ruby, sinun olisi pitänyt nähdä tietotyyppejä, kuten luettelot, joukot, tuples, hashit, sanelut ja niin edelleen.

JavaScript-ohjelmassa ei ole niin monimutkaisia ​​tietotyyppejä - sinulla on yksinkertaisesti taulukot ja objektit. ES6: ssa kuitenkin lisättiin kielelle muutama tietotyyppi ja rakenne, kuten symbolit, joukot ja kartat.

JavaScript-taulukot ovat korkean tason luettelomaisia ​​objekteja, joiden pituusominaisuus ja kokonaislukuominaisuudet ovat indeksejä.

Tässä artikkelissa jaan pari hakkerointia uusien JavaScript-taulukkojen luomiseksi tai jo olemassa olevien kloonaamiseksi.

Matriisien luominen: Matriisinrakentaja

Suosituin tapa taulukkojen luomiseen on taulukon kirjaimisen syntaksin käyttäminen, mikä on hyvin suoraviivaista. Kun kuitenkin haluat luoda dynaamisesti taulukkoja, taulukon kirjaimellinen syntaksi ei välttämättä ole aina paras tapa. Vaihtoehtoinen menetelmä on Array-konstruktorin käyttö.

Tässä on yksinkertainen koodinpätkä, joka osoittaa Array-konstruktorin käytön.

Edellisestä katkelmasta voimme nähdä, että taulukkorakentaja luo taulukot eri tavalla riippuen vastaanotetuista argumenteista.

Uudet taulukot: Määritetty pituus

Katsotaanpa tarkemmin mitä tapahtuu luotaessa uusi tietyn pituinen taulukko. Konstruktori asettaa vain taulukon pituusominaisuuden annettuun pituuteen asettamatta näppäimiä.

Yllä olevasta katkelmasta voi tulla houkutus ajatella, että jokaisen taulukon avaimen arvoksi määritettiin määrittelemätön. Mutta todellisuus on, että näitä avaimia ei koskaan asetettu (niitä ei ole olemassa).

Seuraava kuva selventää sitä:

Tämän vuoksi on turhaa yrittää käyttää mitä tahansa taulukon iterointimenetelmistä, kuten kartta (), suodatin () tai pienentäminen () taulukon käsittelemiseksi. Oletetaan, että haluamme täyttää taulukon jokaisen hakemiston numerolla 5. Yritämme seuraavaa:

Voimme nähdä, että kartta () ei toiminut täällä, koska hakemiston ominaisuuksia ei ole taulukossa - vain pituusominaisuus on olemassa.

Katsotaanpa erilaisia ​​tapoja korjata tämä ongelma.

1. Array.prototype.fill () -sovelluksen käyttö

Täyttö () -menetelmä täyttää kaikki taulukon elementit aloitusindeksistä loppuindeksiin staattisella arvolla. Loppuindeksiä ei sisälly hintaan. Lisätietoja täytöstä () on täällä.

Huomaa, että fill () toimii vain selaimissa, joissa on ES6-tuki.

Tässä on yksinkertainen esimerkki:

Tässä olemme pystyneet täyttämään kaikki luomamme taulukon elementit viidellä. Voit asettaa minkä tahansa staattisen arvon taulukon eri hakemistoille fill () -menetelmällä.

2. Array.from (): n käyttäminen

Array.from () -menetelmä luo uuden, matala-kopioidun taulukon ilmentymän taulukon kaltaisesta tai toistettavasta objektista. Lisätietoja Array.from (): sta löydät täältä.

Huomaa, että Array.from () toimii vain selaimissa, joissa on ES6-tuki.

Tässä on yksinkertainen esimerkki:

Tässä meille on nyt määritetty todelliset määrittelemättömät arvot jokaiselle taulukon elementille Array.from (): n avulla. Tämä tarkoittaa, että voimme nyt mennä eteenpäin ja käyttää menetelmiä, kuten .map () ja .filter () taulukossa, koska hakemistoominaisuudet ovat nyt olemassa.

Vielä yksi huomionarvoinen asia Array.from (): sta on se, että se voi ottaa toisen argumentin, joka on karttafunktio. Sitä kutsutaan kaikkiin taulukon elementteihin. Tämä tekee tarpeettomaksi kutsua .map () Array.from () jälkeen.

Tässä on yksinkertainen esimerkki:

3. Levitysoperaattorin käyttäminen

ES6: een lisätty hajotusoperaattori (...) voidaan käyttää taulukon elementtien hajauttamiseen asettamalla puuttuvat elementit arvoon määrittelemätön. Tämä tuottaa saman tuloksen kuin yksinkertaisesti kutsutaan Array.from (): sta vain taulukko ainoana argumenttina.

Tässä on yksinkertainen esimerkki hajotusoperaattorin käytöstä:

Voit mennä eteenpäin ja käyttää taulukossa menetelmiä, kuten .map () ja .filter (), koska hakemisto-ominaisuudet ovat nyt olemassa.

Array.of (): n käyttö

Aivan kuten näimme luotaessa uusia matriiseja Array-konstruktorilla tai -toiminnolla, Array.of () käyttäytyy hyvin samalla tavalla. Itse asiassa ainoa ero Array.of (): n ja Array: n välillä on siinä, kuinka he käsittelevät heille siirrettyä kokonaislukuargumenttia.

Samalla kun Array.of (5) luo uuden taulukon yhdellä elementillä 5 ja pituusominaisuudella 1, taulukko (5) luo uuden tyhjän taulukon, jossa on 5 tyhjää väliä ja pituusominaisuus 5.

var array1 = ryhmä (5); // [5]
var array2 = taulukko (5); // Array (5) {pituus: 5}

Tämän suuren eron lisäksi Array.of () käyttäytyy kuten Array-konstruktori. Lisätietoja Array.of (): sta löydät täältä.

Huomaa, että Array.of () toimii vain selaimissa, joissa on ES6-tuki.

Siirtyminen ryhmiksi: Array-tykkää ja Iterables

Jos olet kirjoittanut JavaScript-funktioita tarpeeksi kauan, sinun pitäisi jo tietää argumenttiobjektista - joka on matriisimainen objekti, joka on saatavana jokaisessa toiminnossa, jotta se voi pitää luettelon funktion vastaanottamista argumenteista. Vaikka argumenttiobjekti näyttää paljon taulukolta, sillä ei ole pääsyä Array.prototype -menetelmiin.

Ennen ES6: ta näet yleensä seuraavan tyyppisen koodinpätkän, kun yrität muuntaa argumenttiobjektin matriisiksi:

Array.from (): lla tai hajotusoperaattorilla voit mukavasti muuntaa minkä tahansa taulukon kaltaisen objektin taulukkoksi. Siksi sen sijaan, että teisit tämän:

var args = Array.prototype.slice.call (argumentit);

voit tehdä jommankumman seuraavista:

// Array.from ()
var args = Array.from (argumentit);
// Levitä-operaattorin avulla
var args = [... argumentit];

Nämä koskevat myös toistettavissa olevia, kuten seuraavassa kuvassa esitetään:

Tapaustutkimus: Aluetoiminto

Tapaustutkimuksena ennen kuin jatkamme, luomme yksinkertaisen range () -funktion toteuttaaksemme uuden äskettäin oppimamme ryhmä hakkeroinnin. Toiminnolla on seuraava allekirjoitus:

alue (alku: numero, loppu: numero, vaihe: numero) => Matriisi 

Tässä on koodinpätkä:

Käytimme tässä koodinpätkässä Array.from (): sta uuden dynaamisen pituusalueen matriisin ja asettamme sen sitten peräkkäin kasvavat numerot tarjoamalla kartoitustoiminnon.

Huomaa, että yllä oleva koodinpätkä ei toimi selaimissa, joissa ei ole ES6-tukea, paitsi jos käytät monitäyttöjä.

Tässä on joitain tuloksia yllä (koodinpätkässä) määritellyn toimintoalueen () kutsumisesta:

Voit saada live-koodiesityksen suorittamalla seuraavan kynän Codepen: llä:

Kloonausmatriisit: haaste

JavaScript-ohjelmassa taulukot ja objektit ovat viitetyyppejä. Tämä tarkoittaa, että kun muuttujalle osoitetaan taulukko tai objekti, muuttujalle osoitetaan viittaus muistiin, missä taulukko tai objekti on tallennettu.

Matriisit, kuten kaikki muut JavaScript-objektit, ovat vertailutyyppejä. Tämä tarkoittaa, että taulukot kopioidaan viitteen, eikä arvon perusteella.

Viitetyyppien tallentamisella tällä tavalla on seuraavat seuraukset:

1. Samanlaiset taulukot eivät ole yhtä suuret.

Täällä näemme, että vaikka taulukko1 ja taulukko2 sisältävät näennäisesti samat taulukon määritelmät, ne eivät ole samanarvoisia. Tämä johtuu siitä, että viittaus jokaiseen taulukkoon osoittaa eri kohtaan muistissa.

2. Taulukot kopioidaan viitteen perusteella eikä arvon perusteella.

Yritämme tässä kopioida array1 array2: een, mutta periaatteessa teemme osoittaa array2 samaan kohtaan muistissa, johon array1 osoittaa. Siksi sekä taulukko1 että ryhmä2 osoittavat samaan kohtaan muistissa ja ovat yhtä suuret.

Tämä merkitsee sitä, että kun teemme muutoksen taulukkoon 2 poistamalla viimeisen kohteen, taulukon viimeinen kohde poistetaan myös. Tämä johtuu siitä, että muutos on tosiasiallisesti tehty muistiin tallennettuun taulukkoon, kun taas taulukko1 ja taulukko2 ovat vain osoittimet samaan kohtaan muistissa, johon taulukko on tallennettu.

Kloonausmatriisit: Hakkerit

1. Array.prototype.slice ()

Slice () -menetelmä luo matalan kopion taulukon osasta muuttamatta taulukkoa. Saat lisätietoja viipaleesta () täältä.

Temppu on kutsua slice () joko with0: n ainoaksi argumentiksi tai ilman mitään argumentteja:

// O: n kanssa vain argumentti
array.slice (0);
// ilman väitteitä
array.slice ();

Tässä on yksinkertainen esimerkki taulukon kloonaamisesta viipaleella ():

Täällä voit nähdä, että taulukko2 on ryhmän1 klooni, jolla on samat kohteet ja pituus. Ne osoittavat kuitenkin muistin eri paikkoihin, ja sen seurauksena ne eivät ole yhtä suuret. Huomaat myös, että kun teemme muutoksen taulukkoon2 poistamalla viimeisen kohteen, taulukko1 pysyy ennallaan.

2. Array.prototype.concat () -sovelluksen käyttö

Concat () -menetelmää käytetään kahden tai useamman taulukon yhdistämiseen, jolloin saadaan uusi taulukko, kun taas alkuperäiset taulukot jätetään ennallaan. Saat lisätietoja concat (): sta täältä.

Temppu on kutsua concat () joko tyhjellä taulukolla ([]) argumenttina tai ilman mitään argumentteja:

// tyhjällä taulukolla
array.concat ([]);
// ilman väitteitä
array.concat ();

Matriisin kloonaaminen concat (): lla on melko samankaltainen kuin viipale (). Tässä on yksinkertainen esimerkki ryhmän kloonaamisesta concat ():

3. Array.from (): n käyttäminen

Kuten aiemmin näimme, Array.from (): lla voidaan luoda uusi taulukko, joka on matala kopio alkuperäisestä taulukosta. Tässä on yksinkertainen esimerkki:

4. Array-suunnittelun käyttäminen

ES6: n avulla työkalupakkiimme sisältyy joitain tehokkaampia työkaluja, kuten hajottaminen, hajautettu operaattori, nuolitoiminnot ja niin edelleen. Suunnittelu on erittäin tehokas työkalu tietojen keräämiseen monimutkaisista tyypeistä, kuten taulukot ja objektit.

Voit oppia lisää hajottamisesta tästä artikkelista.

Temppu on käyttää lepoparametreiksi kutsuttua tekniikkaa, johon sisältyy matriisin tuhoamisen ja hajotusoperaattorin yhdistelmä seuraavan katkelman mukaisesti:

olkoon [... arrayClone] = originalArray;

Yllä oleva katkelma luo muuttujan nimeltä arrayClone, joka on alkuperäinenArray-klooni. Tässä on yksinkertainen esimerkki ryhmän kloonaamisesta käyttämällä taulukon hajottamista:

Kloonaus: matala vs. syvä

Kaikki tähän mennessä tutkitut ryhmän kloonaustekniikat tuottavat matalan kopion ryhmästä. Tämä ei ole ongelma, jos taulukko sisältää vain alkeelliset arvot. Jos taulukko sisältää kuitenkin sisäkkäisiä objektiviitteitä, nämä viitteet pysyvät ennallaan, vaikka taulukko kloonataan.

Tässä on hyvin yksinkertainen esimerkki tästä:

Huomaa, että taulukon 1 sisäkkäisen taulukon muuttaminen muutti myös taulukon 2 sisäkkäistä taulukkoa ja päinvastoin.

Ratkaisu tähän ongelmaan on luoda syvä kopio taulukosta, ja tähän on muutama tapa.

1. JSON-tekniikka

Helpoin tapa luoda syvä kopio taulukosta on käyttää JSON.stringify () - ja JSON.parse () -yhdistelmää.

JSON.stringify () muuntaa JavaScript-arvon kelvolliseksi JSON-merkkijonoksi, kun taas JSON.parse () muuntaa JSON-merkkijonon vastaavaksi JavaScript-arvoksi tai -objektiksi.

Tässä on yksinkertainen esimerkki:

JSON-tekniikalla on joitain puutteita etenkin, kun kyseessä ovat muut arvot kuin merkkijonot, numerot ja booleanit.

Nämä JSON-tekniikan puutteet voidaan pääasiassa johtua tavasta, jolla JSON.stringify () -menetelmä muuntaa arvot JSON-merkkijonoksi.

Tässä on yksinkertainen osoitus tästä virheestä yritettäessä JSON.stringify () -arvoa, joka sisältää sisäkkäisen funktion.

2. Syvän kopioinnin auttaja

Todellinen vaihtoehto JSON-tekniikalle on oman syväkopiointitoiminnon toteuttaminen referenssityyppien kloonaamiseksi riippumatta siitä ovatko ne taulukot tai objektit.

Tässä on hyvin yksinkertainen ja minimalistinen syväkopiointitoiminto, nimeltään deepClone:

Nyt tämä ei ole parasta syväkopiointitoiminnoista, kuten näet pian joidenkin JavaScript-kirjastojen kanssa - se kuitenkin suorittaa syväkopioinnin melko hyvässä määrin.

3. JavaScripti-kirjastojen käyttö

Äskettäin määrittelemämme syvän kopioinnin auttajatoiminto ei ole riittävän vakaa kloonaamaan kaikenlaisia ​​JavaScript-tietoja, jotka voivat olla sisäkkäisiä monimutkaisissa kohteissa tai ryhmissä.

JavaScript-kirjastot, kuten Lodash ja jQuery, tarjoavat tehokkaampia syväkopiointitoiminnot tukemalla erityyppisiä JavaScript-tietoja.

Tässä on esimerkki, joka käyttää _.cloneDeep () Lodash-kirjastosta:

Tässä on sama esimerkki, mutta käyttämällä $ .extend () jQuery-kirjastosta:

johtopäätös

Tässä artikkelissa olemme pystyneet tutkimaan useita tekniikoita, joilla luodaan dynaamisesti uusia matriiseja ja kloonataan jo olemassa olevia, mukaan lukien muunnetaan taulukkomaiset objektit ja toistettavat matriisiksi.

Olemme myös nähneet, kuinka jotkut ES6: n käyttöön otetuista uusista ominaisuuksista ja parannuksista voivat antaa meille mahdollisuuden suorittaa tehokkaasti tiettyjä manipulointeja taulukkoihin.

Käytimme ominaisuuksia, kuten tuhoamista ja hajotustoimintoa ryhmien kloonaamiseen ja levittämiseen. Voit oppia lisää hajottamisesta tästä artikkelista.

Clap & Follow

Jos pidit tämän artikkelin oivallisena, voit vapaasti antaa suosionosoituksia, ellet muista.

Voit myös seurata minua Mediumissa (Glad Chinda) saadaksesi enemmän oivallisia artikkeleita, joista saatat olla hyödyllisiä. Voit seurata minua myös Twitterissä (@gladchinda).

Hyvää hakkerointia ...