Koodausvinkki: Yritä koodata ilman silmukoita

Saatat löytää parempia ratkaisuja

Koodi Fackebook-projektista. Älä haasta heitä.
Päivitys: Tämä artikkeli on nyt osa kirjaa “Opi koodaus nykyaikaisella JavaScriptillä”.
Lue sen päivitetty versio osoitteesta jscomplete.com/beginning-js.

Edellisessä artikkelissa kirjoitin siitä, kuinka yritetään ratkaista koodaushaasteita käyttämättä if-lauseita voisi auttaa löytämään parempia ratkaisuja. Tässä artikkelissa tutkitaan kuinka ratkaista joitain muita haasteita, mutta tällä kertaa ilman silmukoita.

Silmukoilla tarkoitan pakollisia silmukoita, kuten, varten, sisään, varten, ja, ja tee ... aikaa. Kaikki nämä ovat samanlaisia ​​siinä mielessä, että ne tarjoavat välttämättömän tavan suorittaa iteraatioita. Vaihtoehto on suorittaa iteraatiot deklaratiivisella tavalla.

Pakollinen vs. deklaratiivinen

Tämä on iso aihe. Yksinkertaisin asia mitä voimme sanoa siitä on, että:

  • Imperatiivinen edustaa MITEN
  • Deklaratiivinen edustaa MITÄ

Mitä? Miten? Ja miksi sinun pitäisi välittää?

Pakollinen lähestymistapa edustaa luetteloa vaiheista. Tee tämä ensin, sitten tee se ja sen jälkeen tee jotain muuta. Esimerkiksi: Siirry numeroluettelon päälle yksi kerrallaan ja lisää jokaiselle numero juoksevaan summaan.

Deklaratiivinen lähestymistapa edustaa sitä, mitä meillä on ja mitä tarvitsemme. Esimerkiksi: Meillä on luettelo numeroista ja tarvitsemme näiden numeroiden summan.

Pakollinen kieli on lähempänä nykypäivän tietokoneita, koska he tietävät vain kuinka ohjeet suoritetaan. Deklaratiivinen kieli on lähempänä sitä ajattelumme ja käskyämme. Tee se valmis kiitos. Jotenkin!

Hyvä uutinen on, että tietokonekielet ovat kehittyneet tarjoamaan meille deklaratiivisia tapoja tehdä tarvittavat välttämättömät tietokoneohjeet. Tämä artikkeli keskittyy pakollisten silmukoiden deklaratiivisiin vaihtoehtoihin.

Huomaa, että koodauksen ei tarvitse olla tavalla tai toisella. Kaikilla ei-triviaalseilla tietokoneohjelmilla on todennäköisesti vähän molempia lähestymistapoja. Tietää myös kuinka koodata deklaratiivisesti on hienoa, mutta se ei tarkoita, että sinun ei tarvitse myöskään oppia pakollisia tapoja. Sinun tulisi yksinkertaisesti olla varma käyttämällä molempia.

muuttumattomuudesta

Silmukoiden välttäminen ei ole vain deklaratiivisuutta. Sen avulla voimme myös käsitellä tietojamme muuttumattomasti.

Tietojen muuttumattomuus on toinen suuri aihe, mutta iso kuva on se, että muuttujien ja esiintymien ominaisuuksien tietoja ei muokata sovellustilan edustamiseksi. Sen sijaan tila tallennetaan vaiheittain toimintopuhelujen välillä. Toiminnot kutsuvat toisiaan peräkkäin kehittääkseen alkuperäisen lähtökohdan muiksi datamuodoiksi. Mitään muuttujia ei mutatoida prosessissa.

Sen sijaan, että väärinkäyttäisit tilaa yksinkertaisten toimintojen suorittamisessa, pysyminen pysyvänä on paljon turvallisempaa ja puhtaampaa. Muuttamattomuuden suuri etu on kuitenkin se, kuinka se helpottaa koodin ylläpitämistä ja laajentamista. Esimerkiksi, kun hallitsemme mitä tahansa sovellustilaa muuttumattomalla tavalla, voimme tarkistaa tilan milloin tahansa, peruuttaa tilamuutoksen tai jopa matkustaa takaisin aikaisempiin tiloihin tarkistaaksesi sovelluksen näiden kanssa. Koska tilaa ei muuteta, voimme aina saada sovelluksen muistamaan sen muuttuvat vaiheet.

Koodin luettavuus ja suorituskyky saattavat vaikuttaa, kun teemme asioita muuttumattomalla tavalla. Kuitenkin on monia strategioita, joita voimme käyttää saadaksemme parhaat puolet molemmista maailmoista. Lisää tästä tulevissa artikkeleissa.

rekursio

Toinen tapa välttää välttämättömien silmukoiden käyttö on rekursion avulla.

Rekursio on yksinkertainen. Pidä itse toimintopuhelu (joka luo silmukan) ja suunnittele poistosuhde siitä silmukasta. En ole varma, että rekurssi voidaan luokitella deklaratiiviseksi, mutta se on ehdottomasti vaihtoehto vaniljan pakollisten silmukoiden käyttämiselle. Ole kuitenkin varovainen rekursioissa, koska se ei ehkä toimi yhtä hyvin kuin normaalit silmukat. En myöskään usko, että rekursio tarjoaa useimmissa tapauksissa hyvää luettavuutta.

Joskus rekursio on luonnollisesti helpoin tapa ratkaista haaste. Ilman rekursiota meidän olisi ylläpidettävä ja käytettävä omaa pinorakennettamme (mutta se ei ole myöskään liian vaikea).

Kaikissa tapauksissa on aina hauskaa yrittää ratkaista koodaushaaste ilman mitään pakottavia silmukoita.

Tässä on joitain esimerkkihaasteita silmukkapohjaisilla ratkaisuillaan ja silmukkavapailla ratkaisuillaan. Kaikki esimerkit ovat JavaScript-muodossa.

Kerro minulle, mitkä ratkaisut haluat ja mitkä luulet enemmän tai vähemmän luettavia ratkaisuja.

Haaste # 1: Laske numeroiden luettelon summa

Oletetaan, että meillä on joukko numeroita ja meidän on laskettava näiden lukujen summa.

Tässä on esimerkki testattavaksi:

const-taulukkoOrNumerot = [17, -4, 3,2, 8,9, -1,3, 0, Math.PI];

Tässä on ratkaisu, joka käyttää silmukkaa:

laske summa = 0;
arrayOfNumbers.forEach ((numero) => {
  summa + = numero;
});
console.log (summa);

Huomaa, kuinka meidän piti mutatoida summamuuttuja ratkaisun suorittamiseksi.

Tässä on ratkaisu, joka käyttää erinomaista vähentämistoimintoa:

const summa = arrayOfNumbers.reduce ((acc, luku) =>
  acc + numero
);
console.log (summa);

Mitään ei mutatoitu pelkistyspohjaisella ratkaisulla. Sen sijaan soitimme joukko puheluja takaisinsoitto-toimintoon ja tilaa pidettiin näiden puhelujen välillä, kunnes saavuimme lopulliseen summatilaan.

Tässä on sama yllä oleva haaste, joka on ratkaistu rekursiolla:

const summa = ([numero, ... loput]) => {
  if (lepo.pituus === 0) {
    paluunumero;
  }
  paluu numero + summa (lepo);
};
console.log (summa (arrayOfNumbers))

Summafunktio kutsuu itsensä ja käyttää joka käänteessä loput operaattoria vähentämään summaamaansa taulukkoa. Se pysähtyy, kun vähennetty ryhmä on tyhjä. Vaikka saatat ajatella, että tämä on fiksu ratkaisu, en usko, että se on yhtä luettavissa kuin yksinkertaisen pienentävän puhelun käyttäminen.

Haaste 2: Tee lause sekoitetusta sisällöstä

Oletetaan, että meillä on joukko jousia ja muun tyyppisiä, ja meidän on liityttävä kaikkiin jousiin ja sivuutettava muut tyypit.

Tässä on esimerkki testattavaksi:

const dataArray = [0, 'H', {}, 'e', ​​Math.PI, 'l', 'l', 2/9, 'o!'];

Haluttu lähtö on “Hei!”.

Voit tarkistaa operaattorin typeof avulla, onko arvo tyyppisarjaa.

Tässä on ratkaisu, jossa käytetään yksinkertaista silmukkaa:

olkoon merkkijono = '', i = 0;
kun taas (dataArray [i]! == määrittelemätön) {
  if (typeof dataArray [i] === 'merkkijono') {
    merkkijono + = dataMaailma [i];
  }
  i + = 1;
}
console.log (string);

Tässä on ratkaisu, joka käyttää suodatusmenetelmää yhdistettynä yhdistämismenetelmään:

const string = dataArray.filter (e => typeof e === 'merkkijono')
                        .liittyä seuraan('');
console.log (string);

Huomaa, kuinka suodatusmenetelmän avulla voimme myös päästä eroon if-lauseesta! Ehdollinen käsittely on nyt poistettu suodatinkutsun sisällä.

Haaste 3: Muunna arvot tietueiksi

Oletetaan, että meillä on joukko kirjojen otsikoita, ja meidän on muutettava jokainen nimike esineeksi ja annettava objektille yksilöivä tunnus.

Tässä on esimerkki testattavaksi:

const booksArray = [
  'Puhdas koodi',
  'Koodi valmis',
  'Johdatus algoritmeihin',
];
// Haluttu lähtö
newArray = [
  {id: 1, otsikko: 'Puhdas koodi'},
  {id: 2, otsikko: 'Code Complete'},
  {id: 3, otsikko: 'Johdatus algoritmeihin'},
];

Tässä on ratkaisu, jossa käytetään yksinkertaista silmukkaa:

const newArray = [];
laske laskuri = 1;
(anna kirjojen otsikkoArray) {
  newArray.push ({
    id: laskuri,
    otsikko,
  });
  laskuri + = 1;
}
console.log (newArray);

Tässä on ratkaisu yksinkertaisella karttapuhelulla:

const newArray = booksArray.map ((otsikko, hakemisto) => ({
  tunnus: hakemisto + 1,
  otsikko
}));
console.log (newArray);

Kartta / suodatus / vähentämismenetelmät ovat suosikki menetelmiäni ryhmissä. Voit käyttää niitä tehdä niin monia hienoja asioita! Pysy ajan tasalla toista artikkelia, joka heitä kuvaa. Toistaiseksi jätän sinulle tämän nerokuvan, joka selittää heille hymiöitä! (Hyvitys Steven Luscherille)

Nyt kun olet nähnyt muutamia esimerkkejä, mitä ajattelet? Onko sinulla mitään perusteita näiden koodaustyylijen puolesta tai vastaan?

Kiitos lukemisesta!