Ricerca…


Sintassi

  • []
  • [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]
  • [testa | coda]
  • [1 | [2, 3, 4]] # -> [1,2,3,4]
  • [1 | [2 | [3 | [4 | []]]]] -> [1,2,3,4]
  • 'ciao' = [? h,? e,? l,? l,? o]
  • keyword_list = [a: 123, b: 456, c: 789]
  • keyword_list [: a] # -> 123

Elenchi di parole chiave

Gli elenchi di parole chiave sono elenchi in cui ogni elemento dell'elenco è una tupla di un atomo seguita da un valore.

keyword_list = [{:a, 123}, {:b, 456}, {:c, 789}]

Una notazione abbreviata per la scrittura di elenchi di parole chiave è la seguente:

keyword_list = [a: 123, b: 456, c: 789]

Gli elenchi di parole chiave sono utili per la creazione di strutture dati di coppie valore-chiave ordinate, in cui possono esistere più articoli per una determinata chiave.

Il primo elemento in un elenco di parole chiave per una determinata chiave può essere ottenuto in questo modo:

iex> keyword_list[:b]
456

Un caso d'uso per gli elenchi di parole chiave potrebbe essere una sequenza di attività denominate da eseguire:

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

Questo codice può essere chiamato con un elenco di parole chiave come questo:

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

Le stringhe in elisir sono "binari". Tuttavia, nel codice Erlang, le stringhe sono tradizionalmente "elenchi di caratteri", quindi quando si chiamano le funzioni di Erlang, potrebbe essere necessario utilizzare elenchi di caratteri anziché normali stringhe di elisir.

Mentre le stringhe regolari sono scritte usando virgolette doppie " , le liste dei caratteri vengono scritte usando le virgolette singole ' :

string = "Hello!"
char_list = 'Hello!'

Gli elenchi di caratteri sono semplicemente elenchi di numeri interi che rappresentano i punti di codice di ciascun carattere.

'hello' = [104, 101, 108, 108, 111]

Una stringa può essere convertita in una lista char con to_charlist/1 :

iex> to_charlist("hello")
'hello'

E il contrario può essere fatto con to_string/1 :

iex> to_string('hello')
"hello"

Chiamando una funzione di Erlang e convertendo l'output in una normale stringa di Elisir:

iex> :os.getenv |> hd |> to_string
"PATH=/usr/local/bin:/usr/bin:/bin"

Contro le cellule

Gli elenchi in elisir sono elenchi concatenati. Ciò significa che ogni elemento in un elenco è costituito da un valore, seguito da un puntatore all'elemento successivo nell'elenco. Questo è implementato in Elisir usando cellule cons.

Le celle Contro sono semplici strutture di dati con un valore "sinistro" e un "giusto", o "testa" e una "coda".

A | il simbolo può essere aggiunto prima dell'ultimo elemento in una lista per notificare un elenco (improprio) con una data testa e coda. Quella che segue è una cella singola con 1 come la testa e 2 come la coda:

[1 | 2]

La sintassi standard di Elixir per un elenco è in realtà equivalente alla scrittura di una catena di celle di controllo nidificate:

[1, 2, 3, 4] = [1 | [2 | [3 | [4 | []]]]]

La lista vuota [] viene usata come coda di una cella di controllo per rappresentare la fine di una lista.

Tutti gli elenchi in elisir sono equivalenti alla forma [head | tail] , dove la head è il primo elemento della lista e la tail è il resto della lista, meno la testa.

iex> [head | tail] = [1, 2, 3, 4]
[1, 2, 3, 4]
iex> head
1
iex> tail
[2, 3, 4]

Usando il [head | tail] notation è utile per la corrispondenza dei pattern nelle funzioni ricorsive:

def sum([]), do: 0

def sum([head | tail]) do
  head + sum(tail)
end

Liste di mappatura

map è una funzione nella programmazione funzionale che, data una lista e una funzione, restituisce una nuova lista con la funzione applicata a ciascuna voce in quella lista. In Elixir, la funzione map/2 è nel modulo Enum .

iex> Enum.map([1, 2, 3, 4], fn(x) -> x + 1 end)
[2, 3, 4, 5]

Utilizzando la sintassi di acquisizione alternativa per le funzioni anonime:

iex> Enum.map([1, 2, 3, 4], &(&1 + 1))
[2, 3, 4, 5]

Riferendosi ad una funzione con sintassi di cattura:

iex> Enum.map([1, 2, 3, 4], &to_string/1)
["1", "2", "3", "4"]

Operazioni di elenco concatenate utilizzando l'operatore di condotte:

iex> [1, 2, 3, 4]
...> |> Enum.map(&to_string/1)
...> |> Enum.map(&("Chapter " <> &1))
["Chapter 1", "Chapter 2", "Chapter 3", "Chapter 4"]

Elenco delle comprensioni

L'elisir non ha loop. Invece di quelli per gli elenchi ci sono dei grandi moduli Enum e List , ma ci sono anche delle List comprehension.

Le comprensioni delle liste possono essere utili per:

  • crea nuove liste
iex(1)> for value <- [1, 2, 3], do: value + 1
[2, 3, 4] 
  • filtraggio liste, utilizzando guard espressioni ma usarli senza when parola chiave.
iex(2)> odd? = fn x -> rem(x, 2) == 1 end
iex(3)> for value <- [1, 2, 3], odd?.(value), do: value
[1, 3]
  • crea una mappa personalizzata, usando into parola chiave:
iex(4)> for value <- [1, 2, 3], into: %{}, do: {value, value + 1}
%{1 => 2, 2=>3, 3 => 4}

Esempio combinato

iex(5)> for value <- [1, 2, 3], odd?.(value), into: %{}, do: {value, value * value}
%{1 => 1, 3 => 9}

Sommario

Comprensioni delle liste:

  • usa per for..do sintassi con guardie aggiuntive dopo le virgole e into parola chiave quando si restituisce una struttura diversa da quella degli elenchi, ad es. carta geografica.
  • in altri casi restituire nuove liste
  • non supporta gli accumulatori
  • non può interrompere l'elaborazione quando viene soddisfatta una determinata condizione
  • guard dichiarazioni di guard devono essere prima in ordine dopo for e prima di do o into simboli. L'ordine dei simboli non ha importanza

In base a questi vincoli, le Comprensioni delle liste sono limitate solo per un utilizzo semplice. Nei casi più avanzati l'utilizzo delle funzioni dei moduli Enum e List sarebbe l'idea migliore.

Lista differenza

iex> [1, 2, 3] -- [1, 3]
[2]

-- rimuove la prima occorrenza di un elemento nell'elenco a sinistra per ciascun elemento a destra.

Elenco membri

Utilizzare in operatore per verificare se un elemento è un membro di un elenco.

iex> 2 in [1, 2, 3]
true
iex> "bob" in [1, 2, 3]
false

Convertire le liste in una mappa

Utilizzare Enum.chunk/2 per raggruppare elementi in sotto-elenchi e Map.new/2 per convertirlo in una mappa:

[1, 2, 3, 4, 5, 6]
|> Enum.chunk(2)
|> Map.new(fn [k, v] -> {k, v} end)

Darebbe:

%{1 => 2, 3 => 4, 5 => 6}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow