Do you want to pick up from where you left of?
Take me there

Enum

Et sett med algoritmer for å iterere over kolleksjoner.

Enum

Modulen Enum inneholder over hundre funksjoner som vi kan benytte av oss når vi jobber med kolleksjoner.

Denne leksjonen vil kun dekke en brøkdel av de tilgjengelige funksjonene. For en komplett liste av alle funksjonene, se den offisielle Enum dokumentasjonen, eller Stream for lazy enums.

all?

Ved bruk av all? (og de fleste andre av Enums funksjoner), forsyner vi kolleksjonens elementer med en funksjon. I all? sitt tilfelle, må hele kolleksjonen evalueres til true, ellers vil false bli returnert:

iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 3 end)
false
iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) > 1 end)
true

any?

I motsetning til eksemplet over, vil any? returnere true hvis minst et av elementene evalueres til true:

iex> Enum.any?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 5 end)
true

chunk_every/2

Hvis vi trenger å dele opp kolleksjonen i mindre deler, kan vi benytte oss av funksjonen chunk_every/2:

iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 2)
[[1, 2], [3, 4], [5, 6]]

Det finnes flere alternativer for chunk_every/2, men vi blir ikke å gå igjennom dem. Se chunk_every/4 i den offisielle dokumentasjonen for å lære mer.

chunk_by

Hvis vi trenger å gruppere kolleksjonen vår basert på noe annet enn størrelse, kan vi bruke funksjonen chunk_by. Den tar en gitt kolleksjon og en funksjon som argument, og når retur verdien av funksjonen endrer seg så vil en ny gruppe bli lagd og den starter så å lage den neste gruppen:

iex> Enum.chunk_by(["one", "two", "three", "four", "five"], fn(x) -> String.length(x) end)
[["one", "two"], ["three"], ["four", "five"]]
iex> Enum.chunk_by(["one", "two", "three", "four", "five", "six"], fn(x) -> String.length(x) end)
[["one", "two"], ["three"], ["four", "five"], ["six"]]

map_every

Noen ganger så vil det å dele opp en kolleksjon, ikke være akkurat det vi trenger. Hvis dette er tilfellet så kan map_every/3 brukes til å kun endre på spesifikke elementer.

iex> Enum.map_every([1, 2, 3, 4], 2, fn x -> x * 2 end)
[2, 2, 6, 4]

each

Det kan bli nøvendig å måtte iterere over en kolleksjon uten å produsere en verdi. Vi kan da bruke funksjonen each:

iex> Enum.each(["one", "two", "three"], fn(s) -> IO.puts(s) end)
one
two
three
:ok

Merk: Funksjonen each returnerer atomet :ok.

map

For å forsyne funksjonen vår til hvert element, og produsere en ny kolleksjon kan vi benytte oss av map:

iex> Enum.map([0, 1, 2, 3], fn(x) -> x - 1 end)
[-1, 0, 1, 2]

min

For å finne den minste verdien i kolleksjonen vår kan vi bruke min/1:

iex> Enum.min([5, 3, 0, -1])
-1

Funksjonen min/2 gjør det samme, men tillater oss å spesifisere en standard verdi til Enum i en anonym funksjon som blir sendt inn:

iex> Enum.min([], fn -> :foo end)
:foo

max

max/1 returnerer den største verdien i kolleksjonen:

iex> Enum.max([5, 3, 0, -1])
5

max/2 gjør det samme og oppfører seg som min/2, den tillater oss å sende inn en anonym funksjon med en standard verdi til Enum:

Enum.max([], fn -> :bar end)
:bar

reduce

Vi kan vanne ut kolleksjonen vår ned til kun et enkelt element ved å bruke reduce. Vi kan tilføye en valgfri akkumulator (10 i eksemplet under) til funksjonen vår. Hvis ingen akkumulator er gitt, vil det første elementet bli brukt:

iex> Enum.reduce([1, 2, 3], 10, fn(x, acc) -> x + acc end)
16
iex> Enum.reduce([1, 2, 3], fn(x, acc) -> x + acc end)
6
iex> Enum.reduce(["a","b","c"], "1", fn(x,acc)-> x <> acc end)
"cba1"

sort

Sortering av en kolleksjon er enkelt ved hjelp av to sort funksjoner. Det første alternativet bruker Elixirs eget begrep for sortering til å avgjøre sorteringsrekkefølgen:

iex> Enum.sort([5, 6, 1, 3, -1, 4])
[-1, 1, 3, 4, 5, 6]

iex> Enum.sort([:foo, "bar", Enum, -1, 4])
[-1, 4, Enum, :foo, "bar"]

Den andre alternativet lar oss velge sorteringsrekkefølgen selv:

# Med vår egen funksjon
iex> Enum.sort([%{:val => 4}, %{:val => 1}], fn(x, y) -> x[:val] > y[:val] end)
[%{val: 4}, %{val: 1}]

# uten vår egen funksjon
iex> Enum.sort([%{:count => 4}, %{:count => 1}])
[%{count: 1}, %{count: 4}]

uniq_by

Vi kan benytte oss av uniq_by/2 for å fjerne duplikater fra kolleksjonen vår:

iex> Enum.uniq_by([1, 2, 3, 2, 1, 1, 1, 1, 1], fn x -> x end)
[1, 2, 3]

Denne funksjonen var tidligere kjent som uniq/1 som vil bli deprekert i Elixir 1.4, men fortsatt tilgjengelig (med advarsler).

Har du oppdaget en feil eller ønsker å bidra til leksjonen? Rediger denne leksjonen på GitHub!