Forstå det den Allmektige Redusering

0
74

Jeg var nylig mentoring noen som hadde problemer med .redusere () – metoden i JavaScript. Nemlig, hvordan du får fra dette:

const nums = [1, 2, 3]
la verdi = 0

for (la i = 0; i < nums.lengde; i++) {
verdi += nums[jeg]
}

…til dette:

const nums = [1, 2, 3]
const verdi = nums.redusere((ac, neste) => ac + neste, 0)

De er funksjonelt likeverdig, og de begge summerer alle tallene i tabellen, men det er en bit av paradigmeskifte mellom dem. La oss utforske reduksjonsgir for et øyeblikk fordi de er kraftige, og viktig å ha i programmering verktøykassa. Det er bokstavelig talt hundrevis av andre artikler på reduksjonsgir ut det, og jeg skal lenke opp noen av mine favoritter på slutten.

Hva er en redusering?

Den første og viktigste å forstå om en redusering, er at det vil alltid bare kan returnere en verdi. Jobben med en redusering er å redusere. At en verdi kan være et tall, en streng, en matrise eller et objekt, men det vil alltid bare være en. Reduksjonsgir er virkelig bra for mange ting, men de er spesielt nyttige for å bruke en bit av logikk til en gruppe av verdier og ender opp med en annen singel resultat.

Det er andre ting å nevne: reduksjonsgir vil ikke, på grunn av sin beskaffenhet, mutere din opprinnelige verdi, men at de kommer tilbake for noe annet. La oss gå over at første eksempelet, så kan du se hva som skjer her. Videoen nedenfor forklarer:

Nettleseren din støtter ikke video-taggen.

Det kan være nyttig å se på videoen for å se hvordan utviklingen skjer, men her er koden vi ser på:

const nums = [1, 2, 3]
la verdi = 0

for (la i = 0; i < nums.lengde; i++) {
verdi += nums[jeg]
}

Vi har våre array (1, 2, 3) og den første verdien hvert tall i tabellen vil bli lagt til i (0). Vi går gjennom mengden av tabellen og legge dem til den opprinnelige verdien.

La oss prøve dette litt annerledes:

const nums = [1, 2, 3]
const initialValue = 0

const redusering = function (acc, element) {
tilbake acc + elementet
}

const sum = nums.redusere(redusering, initialValue)

Nå har vi den samme tabellen, men denne gangen er vi ikke muterende som første verdien. I stedet, vi har en initialValue som vil bare bli brukt i starten. Neste, vi kan lage en funksjon som tar en akkumulator og et element. Akkumulatoren er det samlet verdi returneres i den siste bruken som informerer funksjonen hva den neste verdien vil bli lagt til. I dette tilfellet i tillegg, kan du tenke på det som en snøball som ruller nedover et fjell som spiser opp hver verdi i sin vei som det vokser i størrelse av hver spist verdi.

Vi vil bruke .redusere() for å bruke den funksjonen og starte fra den opprinnelige verdien. Dette kan bli forkortet med en pil funksjon:

const nums = [1, 2, 3]
const initialValue = 0

const redusering = (acc, element) => {
tilbake acc + elementet
}

const sum = nums.redusere(redusering, initialValue)

Og så forkortet litt mer! Implisitt kommer tilbake for å vinne!

const nums = [1, 2, 3]
const initialValue = 0

const redusering = (acc, element) => acc + elementet

const sum = nums.redusere(redusering, initialValue)

Nå kan vi bruke funksjonen akkurat der vi kalte det, og vi kan også slenger at opprinnelige verdi direkte i det!

const nums = [1, 2, 3]

const sum = nums.redusere((acc, element) => acc + element,

En akkumulator kan være en skremmende sikt, så du kan tenke på det som den nåværende tilstand av matrisen som vi bruker logikk på innb. er kjøringer.

Call Stack

I tilfelle det er ikke klart hva som skjer, la oss logg ut hva som skjer for hver iterasjon. Reduser er ved hjelp av en callback-funksjon som vil kjøre for hvert element i matrisen. IThe følgende demo vil bidra til å gjøre dette mer tydelig. Jeg har også brukt en annen array ([1, 3, 6]) fordi det å ha tall være den samme som indeksen kan være forvirrende.

Se Penn som viser acc, element, retur av Sarah Drasner (@sdras) på CodePen.

Når vi kjører dette, vil vi se dette ut i konsollen:

“Acc: 0, – Element: 1, returverdi: 1”
“Acc: 1, Element: 3, returverdi: 4”
“Acc: 4, Artikkel: 6, returverdi: 10”

Her er en mer visuell oversikt:

Nettleseren din støtter ikke video-taggen.

  1. Det viser at akkumulatoren er å starte på vår første verdien, 0
  2. Så har vi det første elementet, som er 1, så vår retur-verdien er 1 (0 + 1 = 1)
  3. 1 blir akkumulator på neste gang
  4. Nå har vi 1 som akkumulator og 3 er elementet aince det er neste i rekken.
  5. Verdien som returneres blir 4 (1 + 3 = 4)
  6. Dette, i sin tur, blir akkumulator og det neste elementet på bruken er 6
  7. Som resulterer i 10 (4 + 6 = 10) og er vår endelige verdien siden 6 er det siste nummeret i tabellen

Enkle Eksempler

Nå som vi har fått det under beltet, la oss se på noen vanlige og nyttige ting reduksjonsgir kan gjøre.

Hvor mange av X har vi?

La oss si at du har en rekke tall, og du ønsker å returnere et objekt som rapporterer antall ganger disse tallene oppstå i tabellen. Vær oppmerksom på at dette kan like gjerne gjelde for strenger.

const nums = [3, 5, 6, 82, 1, 4, 3, 5, 82]

const resultat = nums.redusere((tally, amt) => {
tally[amt] ? tally[amt]++ : tally[amt] = 1
tilbake tally
}, {})

– konsollen.logg(resultat)

Se Penn forenklet redusere av Sarah Drasner (@sdras) på CodePen.

Vent, hva gjorde vi bare gjøre?

I utgangspunktet har vi en matrise og det objektet vi kommer til å sette innholdet inn. I vår redusering, vi spørre: har dette elementet eksisterer? Hvis så, la oss inkrement det. Hvis ikke, legger du til den og sett den til 1. På slutten, kan du returnere stemmer teller på hvert element. Så, vi kjører redusere funksjonen, som passerer i både redusering og den opprinnelige verdien.

Ta en matrise og slå den inn i et objekt som viser noen tilstander

La oss si at vi har et utvalg, og vi ønsker å opprette et objekt basert på et sett av betingelser. Redusere kan være stor for dette! Her ønsker vi å opprette et objekt ut av alle forekomster av et nummer som finnes i tabellen, og viser både en merkelig og til og med versjonen av dette nummeret. Hvis nummeret allerede er partall eller oddetall, så er det hva vi vil ha i objektet.

const nums = [3, 5, 6, 82, 1, 4, 3, 5, 82]

// vi kommer til å lage et objekt fra en selv og odd
// versjon for hver forekomst av a-nummer
const resultat = nums.redusere((acc, element) => {
acc[item] = {
odd: element % 2 ? element : element – 1,
selv: element % 2 ? elementet + 1 : element
}
tilbake acc
}, {})

– konsollen.logg(resultat)

Se Penn forenklet redusere av Sarah Drasner (@sdras) på CodePen.

Dette vil skyte ut følgende resultat i konsollen:

1:{odd: 1, even: 2}
3:{odd: 3, even: 4}
4:{odd: 3, even: 4}
5:{odd: 5, even: 6}
6:{odd: 5, even: 6}
82:{odd: 81, selv: 82}

OK, så hva er det som skjer?

Så går vi gjennom hvert element i matrisen, skaper vi en eiendom for partall og oddetall, og basert på en innebygd tilstand med en elastisitet operatør, vil vi enten lagre nummeret eller inkrement det med 1. Den modulus operatør er veldig bra for dette fordi det kan raskt kontrollere for even eller odd — hvis det er delelig med to, det er til og med, hvis ikke, er det merkelig.

Andre ressurser

På toppen, jeg nevnte andre innlegg ut det som er nyttige ressurser for å få mer kjent med rollen som reduksjonsgir. Her er noen av mine favoritter:

  • MDN-dokumentasjonen er fantastisk for dette. Seriøst, det er en av deres beste innlegg, IMO. De beskriver også i en litt mer i detalj hva som skjer dersom du ikke oppgi en startverdi, som vi ikke har dekning i dette innlegget.
  • Daniel Shiffman er alltid fantastisk på å forklare ting på Koding Tog.
  • Et Drypp av JavaScript gjør en god jobb, også.

Jetpack WordPress plugin går på dette nettstedet, slår ikke bare relaterte innlegg nedenfor, men sikkerhet og sikkerhetskopiering, Markdown-støtte, søk nettstedet, kommentar form, sosiale nettverk-tilkoblinger, og mer!