Elixir Language
lijsten
Zoeken…
Syntaxis
- []
- [1, 2, 3, 4]
- [1, 2] ++ [3, 4] # -> [1,2,3,4]
- hd ([1, 2, 3, 4]) # -> 1
- tl ([1, 2, 3, 4]) # -> [2,3,4]
- [hoofd | staart]
- [1 | [2, 3, 4]] # -> [1,2,3,4]
- [1 | [2 | [3 | [4 | []]]]] -> [1,2,3,4]
- 'hallo' = [? h,? e,? l,? l,? o]
- keyword_list = [a: 123, b: 456, c: 789]
- keyword_list [: a] # -> 123
Trefwoordlijsten
Zoekwoordenlijsten zijn lijsten waarbij elk item in de lijst een tuple van een atoom is, gevolgd door een waarde.
keyword_list = [{:a, 123}, {:b, 456}, {:c, 789}]
Een korte notatie voor het schrijven van zoekwoordenlijsten is als volgt:
keyword_list = [a: 123, b: 456, c: 789]
Zoekwoordenlijsten zijn handig voor het maken van geordende sleutel / waarde-paar datastructuren, waar meerdere items kunnen bestaan voor een bepaalde sleutel.
Het eerste item in een zoekwoordenlijst voor een bepaalde sleutel kan als volgt worden verkregen:
iex> keyword_list[:b]
456
Een use case voor trefwoordlijsten kan een reeks benoemde taken zijn die moeten worden uitgevoerd:
defmodule TaskRunner do
def run_tasks(tasks) do
# Call a function for each item in the keyword list.
# Use pattern matching on each {:key, value} tuple in the keyword list
Enum.each(tasks, fn
{:delete, x} ->
IO.puts("Deleting record " <> to_string(x) <> "...")
{:add, value} ->
IO.puts("Adding record \"" <> value <> "\"...")
{:update, {x, value}} ->
IO.puts("Setting record " <> to_string(x) <> " to \"" <> value <> "\"...")
end)
end
end
Deze code kan zo worden opgeroepen met een zoekwoordenlijst:
iex> tasks = [
...> add: "foo",
...> add: "bar",
...> add: "test",
...> delete: 2,
...> update: {1, "asdf"}
...> ]
iex> TaskRunner.run_tasks(tasks)
Adding record "foo"...
Adding record "bar"...
Adding record "test"...
Deleting record 2...
Setting record 1 to "asdf"...
Char Lijsten
Strings in Elixir zijn "binaries". In de Erlang-code zijn strings echter traditioneel "char-lijsten", dus als je Erlang-functies aanroept, moet je misschien char-lijsten gebruiken in plaats van reguliere Elixir-strings.
Terwijl normale tekenreeksen met dubbele aanhalingstekens worden geschreven "
, worden char-lijsten met enkele aanhalingstekens geschreven '
:
string = "Hello!"
char_list = 'Hello!'
Char lijsten zijn eenvoudig lijsten van gehele getallen die de codepunten van elk karakter vertegenwoordigen.
'hello' = [104, 101, 108, 108, 111]
Een string kan worden omgezet in een char-lijst met to_charlist/1
:
iex> to_charlist("hello")
'hello'
En het omgekeerde kan worden gedaan met to_string/1
:
iex> to_string('hello')
"hello"
Een Erlang-functie oproepen en de uitvoer converteren naar een normale Elixir-reeks:
iex> :os.getenv |> hd |> to_string
"PATH=/usr/local/bin:/usr/bin:/bin"
Nadelen cellen
Lijsten in Elixir zijn gekoppelde lijsten. Dit betekent dat elk item in een lijst bestaat uit een waarde, gevolgd door een aanwijzer naar het volgende item in de lijst. Dit wordt geïmplementeerd in Elixir met behulp van cons cellen.
Tegens cellen zijn eenvoudige datastructuren met een "linker" en een "rechter" waarde, of een "kop" en een "staart".
A |
symbool kan worden toegevoegd vóór het laatste item in een lijst om een (onjuiste) lijst met een gegeven kop en staart aan te geven. Het volgende is een enkele nadelige cel met 1
als het hoofd en 2
als de staart:
[1 | 2]
De standaard Elixir-syntaxis voor een lijst is eigenlijk gelijk aan het schrijven van een keten van geneste cons-cellen:
[1, 2, 3, 4] = [1 | [2 | [3 | [4 | []]]]]
De lege lijst []
wordt gebruikt als de staart van een nadelencel om het einde van een lijst weer te geven.
Alle lijsten in Elixir zijn gelijk aan de vorm [head | tail]
, waarbij head
het eerste item van de lijst is en tail
de rest van de lijst, minus de kop.
iex> [head | tail] = [1, 2, 3, 4]
[1, 2, 3, 4]
iex> head
1
iex> tail
[2, 3, 4]
Gebruik van de [head | tail]
notatie is handig voor patroonvergelijking in recursieve functies:
def sum([]), do: 0
def sum([head | tail]) do
head + sum(tail)
end
Lijsten met kaarten
map
is een functie in functioneel programmeren die een lijst en een functie geeft en een nieuwe lijst retourneert met de functie toegepast op elk item in die lijst. In Elixir bevindt de map/2
functie zich in de Enum- module.
iex> Enum.map([1, 2, 3, 4], fn(x) -> x + 1 end)
[2, 3, 4, 5]
De alternatieve syntaxis voor vastleggen gebruiken voor anonieme functies:
iex> Enum.map([1, 2, 3, 4], &(&1 + 1))
[2, 3, 4, 5]
Verwijzend naar een functie met vastlegsyntaxis:
iex> Enum.map([1, 2, 3, 4], &to_string/1)
["1", "2", "3", "4"]
Chaining list operaties met behulp van de pipe operator:
iex> [1, 2, 3, 4]
...> |> Enum.map(&to_string/1)
...> |> Enum.map(&("Chapter " <> &1))
["Chapter 1", "Chapter 2", "Chapter 3", "Chapter 4"]
Lijstbegrippen
Elixir heeft geen lussen. In plaats van ze voor lijsten zijn er geweldige Enum
en List
modules, maar er zijn ook Lijstbegrippen.
Lijstbegrippen kunnen nuttig zijn om:
- nieuwe lijsten maken
iex(1)> for value <- [1, 2, 3], do: value + 1
[2, 3, 4]
- filteren van lijsten, met behulp van
guard
uitdrukkingen maar je ze gebruiken zonderwhen
zoekwoord.
iex(2)> odd? = fn x -> rem(x, 2) == 1 end
iex(3)> for value <- [1, 2, 3], odd?.(value), do: value
[1, 3]
- aangepaste kaart maken
into
trefwoord:
iex(4)> for value <- [1, 2, 3], into: %{}, do: {value, value + 1}
%{1 => 2, 2=>3, 3 => 4}
Gecombineerd voorbeeld
iex(5)> for value <- [1, 2, 3], odd?.(value), into: %{}, do: {value, value * value}
%{1 => 1, 3 => 9}
Samenvatting
Lijstbegrippen:
- gebruikt
for..do
syntax met extra bewakers na komma's eninto
trefwoord bij het retourneren van een andere structuur dan lijsten ie. kaart. - in andere gevallen retourneren nieuwe lijsten
- ondersteunt geen accumulatoren
- kan de verwerking niet stoppen wanneer aan bepaalde voorwaarden is voldaan
-
guard
moeten eerst in volgorde zijnfor
en vóórdo
ofinto
symbolen. De volgorde van symbolen doet er niet toe
Volgens deze beperkingen zijn lijstbegrippen alleen beperkt voor eenvoudig gebruik. In meer geavanceerde gevallen zou het gebruik van functies uit Enum
en List
modules het beste zijn.
Lijst verschil
iex> [1, 2, 3] -- [1, 3]
[2]
--
verwijdert het eerste exemplaar van een item in de linkerlijst voor elk item aan de rechterkant.
Lijst lidmaatschap
Gebruik in
operator om te controleren of een element lid is van een lijst.
iex> 2 in [1, 2, 3]
true
iex> "bob" in [1, 2, 3]
false
Lijsten omzetten in een kaart
Gebruik Enum.chunk/2
om elementen in Enum.chunk/2
te groeperen en Map.new/2
om het in een Kaart om te zetten:
[1, 2, 3, 4, 5, 6]
|> Enum.chunk(2)
|> Map.new(fn [k, v] -> {k, v} end)
Zou geven:
%{1 => 2, 3 => 4, 5 => 6}