Fork me on GitHub

Enum

Some contents of this translation may be outdated.
Several major changes were applied to the original lesson since the last update.

Sada algoritmov pre iterovanie nad kolekciami.

Obsah

Enum

Modul Enum obsahuje vyše stovku funkcií pre prácu s kolekciami, o ktorých sme sa dozvedeli v minulej lekcii.

Táto lekcia pokrýva len malú podmnožinu týchto funkcií - kompletný zoznam aj s príkladmi použitia nájdete v oficiálnej dokumentácii modulu Enum. Zaujímať vás môžu aj funkcie na prácu s “lazy enumeration” z modulu Stream.

all?

Funkcia all?, rovnako ako väčšina ostatných funkcii z modulu Enum, berie ako svoj argument funkciu, ktorú potom aplikuje na všetky prvky kolekcie. Ak táto funkcia vráti pre všetky prvky true, funkcia all? vráti hodnotu true, inak false:

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?

Na rozdiel od predošlej, vráti funkcia any? hodnotu true vtedy, ak sa aspoň jeden prvok kolekcie vyhodnotí ako true.

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

chunk

Keď potrebujete rozbiť kolekciu do niekoľkých menších, hodí sa vám funckia chunk:

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

Táto funckia má niekoľko možností použitia, pozrite sa do oficiálnej dokumentácie: chunk/2.

chunk_by

Ak potrebujete rozdeliť kolekciu do menších na základe niečoho iného, než ich veľkosť, použite funkciu chunk_by. Ako argumenty funkcia berie kolekciu (Enum) a funkciu - ak sa zmení jej výstup, ukončí sa aktuálna podkolekcia a začne sa vytvárať ďalšia:

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"]]

each

Často sa stretnete s potrebou cyklovať nad kolekciu bez toho, aby ste vracali nejakú novú hodnotu. Na tento účel je ideálna funckia each:

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

Poznámka: Funkcia each vracia atom :ok.

map

Aplikuje poskutnutú funkciu na každý prvok kolekcie a vráti novú kolekciu s výsledkami týchto aplikácií:

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

min

Nájde a vráti najmenšiu hodnotu v kolekcii:

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

max

Nájde a vráti najväčšiu hodnotu v kolekcii:

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

reduce

Postupne zredukuje kolekciu na jedinú hodnotu. Na vstupe očakáva kolekciu, počiatočnú hodnotu akumulátora (ak žiadna nie je poskytnutá, použije sa prvý prvok kolekcie) a funkciu. Táto funkcia dostane ako argumenty vždy ďalší prvok kolekcie a aktuálnu hodnotu akumulátora. Vráti novú hodnotu akumulátora, ktorá sa zasa použije v ďalšom kole cyklu:

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

Na triedenie kolekcií máme k dispozícii dve sort funkcie. Prvá používa na určenie poradia prvkov term ordering jazyka Elixir (t.j. triedi podľa priority dátových typov):

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"]

Druhá možnosť je poskytnúť ako druhý argument triediacu funkciu:

# s triediacou funkciou
iex> Enum.sort([%{:val => 4}, %{:val => 1}], fn(x, y) -> x[:val] > y[:val] end)
[%{val: 4}, %{val: 1}]

# bez triediacej funkcie
iex> Enum.sort([%{:count => 4}, %{:count => 1}])
[%{count: 1}, %{count: 4}]

uniq

Odstráni z kolekcie duplikáty:

iex> Enum.uniq([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
[1, 2, 3, 4]

Zdieľaj túto stránku