Returning vs Mutating

let pets = [
  {name: "Meowsalot", species: "cat", age: 2},
  {name: "Barksalot", species: "dog", age: 3},
  {name: "Purrsloud, species: "cat", age: 8}
]

pets.push({name: "Puppster", species: "dog", age: 1})
console.log(pets);

Forskjellen på returning og mutating er hvorvidt en funksjon endrer data, eller bare viser oss dataene. Push er derfor en mutating funksjon, fordi den legger til et element i et array som finnes fra før.

En array-metode av høyere orden som kan være nyttig er map(). Den tar inn en funksjon som et argument, som kjører den funksjonen for hvert element i arrayet, i vårt tilfelle pets. Den returnerer dette som et nytt array.

pets.map(nameOnly)

function nameOnly() {
  return "hello"
}

Men per nå vil dette skje i kulissene, så vi kan ikke se resultatet. La oss endre dette:

let ourTest = pets.map(nameOnly)

function nameOnly() {
  return "hello"
}

console.log(ourTest)

La oss nå lage en parameter i nameOnly funksjonen vår. Den første parameteren vil komme fra arrayet og representerer hvert element

let ourTest = pets.map(nameOnly)

function nameOnly(element) {
  return element.name
}

console.log(ourTest)

Vi får da ut et array med navnene til alle i pets-arrayet.

Hva om vi kun ønsker å hente ut hundene fra pets-arrayet? Det finnes en array-metode som heter filter(), som også er en funksjon av en høyere orden. Denne returnerer også et nytt array, uten å endre det originale arrayet.

Vi lager en variabel som vi kan logge ut til console, og lager en funksjon som tar inn en parameter, på samme måte som over:

let dogs = pets.filter(onlyDogs)

function onlyDogs() {
  // linjen under blir som en implisitt "if"
  return x.species == "dogs"
}

console.log(dogs)

La oss lage en funksjon til, som viser oss alle baby-pets:

function onlyBabies(x) {
  return x.age < 3
}

Vi vet at arraynavn.filter() returnerer et nytt array med de filtrerte elementene. Det vil si at vi kan bruke array-metoder på det nye arrayet, og hvis de metodene også returnerer et array, kan vi fortsette å benytte array-metoder. La oss si at vi ønsker navnet på alle hunder som er under 3 år:

// Vi begynner først med å lage en variabel som finner alle hunder
pets.filter(onlyDogs)
// så filtrerer vi på alder:
pets.filter(onlyDogs).filter(onlyBabies)
// Og til slutt henter vi ut kun navnet
pets.filter(onlyDogs).filter(onlyBabies).map(nameOnly)

Til slutt står vi da igjen med:

let babyDogNames = pets.filter(onlyDogs).filter(onlyBabies).map(nameOnly);
console.log(babyDogNames)

Et viktig poeng med disse array-metodene er at alle lager nye arrays, og endrer ikke det originale arrayet; de returnerer et array, men muterer ikke det originale arrayet.