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 utan when 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 och into 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 efter for och innan do eller into 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}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow