Elixir Language
listor
Sök…
Syntax
- []
- [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]
- [huvud | svans]
- [1 | [2, 3, 4]] # -> [1,2,3,4]
- [1 | [2 | [3 | [4 | []]]]] -> [1,2,3,4]
- 'hej' = [? h,? e,? l,? l,? o]
- nyckelordlista = [a: 123, b: 456, c: 789]
- nyckelordlista [: a] # -> 123
Sökordslistor
Nyckelordslistor är listor där varje objekt i listan är en tupel av en atom följt av ett värde.
keyword_list = [{:a, 123}, {:b, 456}, {:c, 789}]
En kort notation för att skriva nyckelordslistor är följande:
keyword_list = [a: 123, b: 456, c: 789]
Nyckelordslistor är användbara för att skapa beställda nyckelvärdesparstrukturer, där flera objekt kan existera för en given nyckel.
Det första objektet i en sökordslista för en given nyckel kan erhållas på så sätt:
iex> keyword_list[:b]
456
Ett användningsfall för nyckelordslistor kan vara en sekvens med namngivna uppgifter som ska köras:
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
Den här koden kan kallas med en sökordslista så:
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 Lists
Strängar i Elixir är "binärer". Men i Erlang-koden är strängar traditionellt "char-listor", så när du ringer Erlang-funktioner kan du behöva använda char-listor istället för vanliga Elixir-strängar.
Medan vanliga strängar skrivs med dubbla citat "
skrivs charlistor med hjälp av enstaka citat '
:
string = "Hello!"
char_list = 'Hello!'
Charlistor är helt enkelt listor över heltal som representerar kodens poäng för varje tecken.
'hello' = [104, 101, 108, 108, 111]
En sträng kan konverteras till en to_charlist/1
med to_charlist/1
:
iex> to_charlist("hello")
'hello'
Och det omvända kan göras med to_string/1
:
iex> to_string('hello')
"hello"
Ringa en Erlang-funktion och konvertera utgången till en vanlig Elixir-sträng:
iex> :os.getenv |> hd |> to_string
"PATH=/usr/local/bin:/usr/bin:/bin"
Nackdelar celler
Listor i Elixir är länkade listor. Detta innebär att varje objekt i en lista består av ett värde, följt av en pekare till nästa objekt i listan. Detta implementeras i Elixir med hjälp av nackceller.
Nackceller är enkla datastrukturer med ett "vänster" och ett "höger" värde eller ett "huvud" och en "svans".
A |
symbol kan läggas till före det sista objektet i en lista för att notera en (felaktig) lista med ett givet huvud och svans. Följande är en enda nackdel med 1
som huvud och 2
som svans:
[1 | 2]
Den vanliga Elixir-syntaxen för en lista är faktiskt motsvarande att skriva en kedja med kapslade nackdelceller:
[1, 2, 3, 4] = [1 | [2 | [3 | [4 | []]]]]
Den tomma listan []
används som svansen på en nackcell för att representera slutet på en lista.
Alla listor i Elixir motsvarar formen [head | tail]
, där head
är det första objektet i listan och tail
är resten av listan minus huvudet.
iex> [head | tail] = [1, 2, 3, 4]
[1, 2, 3, 4]
iex> head
1
iex> tail
[2, 3, 4]
Använda [head | tail]
notation är användbar för mönster matchning i rekursiva funktioner:
def sum([]), do: 0
def sum([head | tail]) do
head + sum(tail)
end
Kartläggningslistor
map
är en funktion i funktionell programmering som ger en lista och en funktion, returnerar en ny lista med funktionen tillämpad på varje objekt i den listan. I Elixir finns map/2
funktionen i Enum- modulen.
iex> Enum.map([1, 2, 3, 4], fn(x) -> x + 1 end)
[2, 3, 4, 5]
Använda den alternativa fångssyntaxen för anonyma funktioner:
iex> Enum.map([1, 2, 3, 4], &(&1 + 1))
[2, 3, 4, 5]
Med hänvisning till en funktion med fångssyntax:
iex> Enum.map([1, 2, 3, 4], &to_string/1)
["1", "2", "3", "4"]
Kedja listfunktioner med röroperatören:
iex> [1, 2, 3, 4]
...> |> Enum.map(&to_string/1)
...> |> Enum.map(&("Chapter " <> &1))
["Chapter 1", "Chapter 2", "Chapter 3", "Chapter 4"]
Lista förståelser
Elixir har inte öglor. I stället för dem för listor finns det stora Enum
och List
moduler, men det finns också Listförståelser.
Listförståelser kan vara användbara för:
- skapa nya listor
iex(1)> for value <- [1, 2, 3], do: value + 1
[2, 3, 4]
- filterlistor, använda
guard
men du använder dem utanwhen
nyckelord.
iex(2)> odd? = fn x -> rem(x, 2) == 1 end
iex(3)> for value <- [1, 2, 3], odd?.(value), do: value
[1, 3]
- skapa anpassade kartlägga, med hjälp av
into
sökord:
iex(4)> for value <- [1, 2, 3], into: %{}, do: {value, value + 1}
%{1 => 2, 2=>3, 3 => 4}
Kombinerat exempel
iex(5)> for value <- [1, 2, 3], odd?.(value), into: %{}, do: {value, value * value}
%{1 => 1, 3 => 9}
Sammanfattning
Listförståelser:
- använder för
for..do
syntax med ytterligare vakter efter komma ochinto
nyckelord när du returnerar annan struktur än listor, dvs. Karta. - i andra fall returnerar nya listor
- stöder inte ackumulatorer
- kan inte sluta behandla när vissa villkor är uppfyllda
-
guard
måste vara först i ordning efterfor
och innando
ellerinto
symboler. Ordning av symboler spelar ingen roll
Enligt dessa begränsningar är listförståelser endast begränsade för enkel användning. I mer avancerade fall skulle det vara den bästa idén att använda funktioner från Enum
och List
moduler.
Lista skillnad
iex> [1, 2, 3] -- [1, 3]
[2]
--
tar bort den första förekomsten av ett objekt i den vänstra listan för varje objekt till höger.
Lista medlemskap
Använd in
operatören för att kontrollera om ett element är medlem i en lista.
iex> 2 in [1, 2, 3]
true
iex> "bob" in [1, 2, 3]
false
Konvertera listor till en karta
Använd Enum.chunk/2
att gruppera element i Map.new/2
och Map.new/2
att konvertera det till en karta:
[1, 2, 3, 4, 5, 6]
|> Enum.chunk(2)
|> Map.new(fn [k, v] -> {k, v} end)
Skulle ge:
%{1 => 2, 3 => 4, 5 => 6}