Kolekcie
Listy, tuples, keyword listy a mapy.
Listy
Listy sú jednoduché kolekcie hodnôt, ktoré môžu obsahovať viacero dátových typov. Prvky sa v zozname môžu aj opakovať:
iex> [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
Elixir implementuje listy ako lineárne zoznamy (linked lists). To znamená, že prístup k dĺžke zoznamu je operácia s lineárnou časovou zložitosťou (O(n)
). Z tohto dôvodu je zvyčajne rýchlejšie nové prvky pridávať na začiatok zoznamu, než na jeho koniec:
iex> list = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
# Pridávanie na začiatok (rýchle)
iex> ["π" | list]
["π", 3.14, :pie, "Apple"]
# Pridávanie na koniec (pomalé)
iex> list ++ ["Cherry"]
[3.14, :pie, "Apple", "Cherry"]
Spájanie listov
Spájanie listov využíva operátor ++/2
:
iex> [1, 2] ++ [3, 4, 1]
[1, 2, 3, 4, 1]
Poznámka k formátu zápisu funkcií a operátorov, ktorý je použitý v príkladoch: v Elixire má názov funkcie dve časti: meno funkcie (v tomto prípade ++
) a početnosť parametrov (arity - v tomto prípade 2
). Operátor ++
teda vyžaduje, aby sme mu dodali 2 parametre pri jeho volaní. Pri popise väčšiny funkcii je uvedené jej meno a počet parametrov, ktoré sú spojené lomítkom. O tomto si povieme detailnejšie neskôr, táto poznámka ti zatiaľ pomôže pochopiť túto notáciu.
Odčítavanie listov
Odčítanie listov (list subtraction) zabezpečuje operátor --/2
, pri ktorom je bezpečné odčítať aj chýbajúcu hodnotu:
iex> ["foo", :bar, 42] -- [42, "bar"]
["foo", :bar]
Musíme však dbať na duplicitné hodnoty. Pre každý prvok na pravej strane operácie sa vymaže prvý výskyt na ľavej strane:
iex> [1,2,2,3,2,3] -- [1,2,3,2]
[2, 3]
Pozn.: Odčítanie listov používa striktné porovnanie na nájdenie zhodných hodnôt.
Head / Tail
Pri používaní zoznamov je bežné pracovať s hlavou a chvostom zoznamu. Hlava (head) je prvý element zoznamu a chvost (tail) je zoznam, ktorý obsahuje zvyšok prvkov. Elixir poskytuje dve užitočné funkcie, hd
a tl
, pre prácu s týmito časťami:
iex> hd [3.14, :pie, "Apple"]
3.14
iex> tl [3.14, :pie, "Apple"]
[:pie, "Apple"]
Naviac môžeme použiť pattern matching a operátor |
(cons), ktorý rozdelí zoznam na hlavu a chvost. O tomto vzore si povieme v neskorších lekciách:
iex> [head | tail] = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
iex> head
3.14
iex> tail
[:pie, "Apple"]
Tuples
Tuples sú podobné zoznamom, no v pamäti sú uložené ako súvislá oblasť. Vďaka tomu je prístup k dĺžke rýchly ale modifikácia je nákladná, keďže celý zmenený tuple musí byť prekopírovaný do pamäte. Tuples definujeme pomocou zložených zátvoriek:
iex> {3.14, :pie, "Apple"}
{3.14, :pie, "Apple"}
Bežne sa tuples používajú ako mechanizmus pre návratové hodnoty z funkcií - v kapitole o pattern matchingu si ukážeme, ako užitočné to skutočne je:
iex> File.read("path/to/existing/file")
{:ok, "... obsah ..."}
iex> File.read("path/to/unknown/file")
{:error, :enoent}
Keyword listy
Keyword listy a mapy sú asociatívnymi kolekciami Elixiru. Keyword listy sú zoznamy dvojprvkových tuplov, pričom prvým prvkom v každom tuple je vždy atóm. Výkonom sú na tom rovnako ako listy:
iex> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex> [{:foo, "bar"}, {:hello, "world"}]
[foo: "bar", hello: "world"]
Pre keyword listy je charakteristické:
- Kľúčmi sú Atomy.
- Kľúče sú zoradené.
- Kľúče nemusia byť unikátne.
Z týchto dôvodov sú keyword listy najčastejšie využívané na odovzdanie doplnkových parametrov (options) do funkcií.
Mapy
Na uchovávanie informácií typu kľúč-hodnota (key-value store) slúžia v Elixire Mapy. Na rozdiel od keyword listov umožňujú ako kľúč akýkoľvek dátový typ a nie sú zoradené. Mapu môžeme definovať syntaxou %{}
:
iex> map = %{:foo => "bar", "hello" => :world}
%{:foo => "bar", "hello" => :world}
iex> map[:foo]
"bar"
iex> map["hello"]
:world
Od verzie 1.2 dovolí Elixir použiť ako kľúče aj premenné:
iex> key = "hello"
"hello"
iex> %{key => "world"}
%{"hello" => "world"}
Keď do mapy pridáme prvok už s existujúcim kľúčom, prepíše pôvodnú hodnotu.
iex> %{:foo => "bar", :foo => "hello world"}
%{foo: "hello world"}
Ako môžeme vidieť z výstupu vyššie, mapy, ktoré používajú ako kľúče iba atómy majú špeciálnu syntax:
iex> %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> %{foo: "bar", hello: "world"} == %{:foo => "bar", :hello => "world"}
true
Navyše existuje špeciálna syntax pre prístup ku kľúčom, ktoré sú atómy:
iex> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> map.hello
"world"
Ďalšia zaujímavá vlastnosť máp je, že poskytujú vlastnú syntax na ich zmenu:
iex> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> %{map | foo: "baz"}
%{foo: "baz", hello: "world"}
Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!