Συλλογές
Λίστες, tuples, λίστες λέξεων κλειδί και χάρτες.
Λίστες
Οι λίστες είναι απλές συλλογές τιμών, μπορεί να περιλαμβάνουν πολλαπλούς τύπους. Οι λίστες μπορεί να περιλαμβάνουν μη μοναδικές τιμές:
iex> [3.41, :pie, "Apple"]
[3.41, :pie, "Apple"]
Η Elixir υλοποιεί μια λίστα σαν συνδεδεμένη λίστα.
Αυτό σημαίνει ότι η πρόσβαση στο σύνολο της λίστας είναι μια O(n)
λειτουργία.
Για αυτό το λόγο, είναι συνήθως πιο γρήγορο να προσθέτετε δεδομένα στην αρχή, παρά στο τέλος:
iex> list = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
# Prepending (fast)
iex> ["π" | list]
["π", 3.14, :pie, "Apple"]
# Appending (slow)
iex> list ++ ["Cherry"]
[3.14, :pie, "Apple", "Cherry"]
Ένωση Λιστών
Η ένωση λιστών χρησιμοποιεί τον τελεστή ++/2
:
iex> [1, 2] ++ [3, 4, 1]
[1, 2, 3, 4, 1]
Μια σημείωση για τη μορφή ονόματος που χρησιμοποιήθηκε από πάνω (++/2
).
Στην Elixir (και την Erlang, πάνω στην οποία έχει χτιστεί η Elixir), μία συνάρτηση ή ένας χειριστής έχουν δύο μέρη: το όνομα που του δίνετε (εδώ ++
) και την τάξη της.
Η τάξη είναι ένα σημαντικό μέρος της ομιλίας μας για την Elixir (και την Erlang).
Είναι ο αριθμός ορισμάτων που δέχεται μια συνάρτηση (δύο σε αυτή την περίπτωση).
Η τάξη και το δοσμένο όνομα συνδυάζονται με μία κάθετο. Θα μιλήσουμε περισσότερο για αυτό αργότερα.
Αυτή η γνώση θα σας βοηθήσει να κατανοήσετε την σημειογραφία για τώρα.
Αφαίρεση Λιστών
Παρέχεται υποστήριξη για αφαίρεση μέσω του τελεστή --/2
.
Είναι ασφαλές να αφαιρέσετε μια τιμή που δεν υπάρχει:
iex> ["foo", :bar, 42] -- [42, "bar"]
["foo", :bar]
Να προσέχετε διπλότυπες τιμές. Για κάθε στοιχείο στα δεξιά, η πρώτη φορά που συνταντάται στα αριστερά αφαιρείται:
iex> [1,2,2,3,2,3] -- [1,2,3,2]
[2, 3]
Σημείωση: Χρησιμοποιεί αυστηρή σύγκριση για να αντιπαραβάλει τις τιμές. Για παράδειγμα:
iex> [2] -- [2.0]
[2]
iex> [2.0] -- [2.0]
[]
Κεφαλή / Ουρά
Όταν χρησιμοποιείτε λίστες είναι σύνηθες να δουλέυετε με την κεφαλή και την ουρά μιας λίστας.
Η κεφαλή είναι το πρώτο στοιχείο της λίστας, ενώ η ουρά είναι τα υπόλοιπα στοιχεία.
Η Elixir παρέχει δύο χρήσιμες συναρτήσεις, τις hd
και tl
, για να δουλέυετε με αυτά τα μέρη:
iex> hd [3.41, :pie, "Apple"]
3.41
iex> tl [3.41, :pie, "Apple"]
[:pie, "Apple"]
Επιπρόσθετα στις προαναφερθείσες συναρτήσεις, μπορείτε να χρησιμοποιήσετε αντιπαραβολές προτύπων και τον τελεστή σωλήνα |
για να χωρίσετε μια λίστα στην κεφαλή και την ουρά.
Θα μάθουμε περισσότερα για αυτό το πρότυπο σε μεταγενέστερα μαθήματα:
iex> [head | tail] = [3.41, :pie, "Apple"]
[3.41, :pie, "Apple"]
iex> head
3.41
iex> tail
[:pie, "Apple"]
Τούπλες
Οι τούπλες είναι όμοιες με τις λίστες αλλά αποθηκεύονται συνεχόμενα στη μνήμη. Αυτό κάνει την πρόσβαση στο σύνολό τους γρήγορη αλλά ακριβή την μετατροπή: η νέα τούπλα θα πρέπει να αντιγραφεί συνολικά εξ’ ολοκλήρου στη μνήμη. Οι τούπλες ορίζονται με άγκιστρα:
iex> {3.41, :pie, "Apple"}
{3.41, :pie, "Apple"}
Είναι σύνηθες για τις τούπλες να χρησιμοποιούνται σαν μηχανισμός επιστροφής πρόσθετων πληροφοριών από τις συναρτήσεις. Αυτή η χρησιμότητα θα είναι πιο εμφανής όταν θα ασχοληθούμε με τις αντιπαραβολές προτύπων:
iex> File.read("διαδρομή/προς/υπάρχων/αρχείο")
{:ok, "... contents ..."}
iex> File.read("διαδρομή/προς/άγνωστο/αρχείο")
{:error, :enoent}
Λίστες Λέξεων Κλειδί
Οι λίστες λέξεων κλειδί και οι χάρτες είναι οι συσχετισμένες συλλογές στην Elixir. Στην Elixir, μια λίστα λέξεων κλειδί είναι μια ειδική λίστα από τούπλες δύο στοιχείων των οποίων το πρώτο στοιχείο είναι ένα άτομο. Έχουν τις ίδιες επιδόσεις με τις λίστες:
iex> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex> [{:foo, "bar"}, {:hello, "world"}]
[foo: "bar", hello: "world"]
Τα τρία χαρακτηριστικά των λιστών λέξεων κλειδί δίνουν έμφαση στην σπουδαιότητά τους:
- Τα κλειδιά είναι άτομα.
- Τα κλειδιά είναι ταξινομημένα.
- Τα κλειδιά δεν είναι μοναδικά.
Για αυτούς τους λόγους, οι λίστες λέξεων κλειδί χρησιμοποιούνται περισσότερο για να περνούν επιλογές σε συναρτήσεις.
Χάρτες
Στην Elixir οι χάρτες είναι η βασικότερη επιλογή για αποθήκευση κλειδιών-τιμών.
Αντίθετα με τις λίστες λέξεων κλειδί, επιτρέπουν κλειδιά οποιουδήποτε τύπου και δεν είναι ταξινομημένοι.
Μπορείτε να ορίσετε ένα χάρτη με το συντακτικό %{}
:
iex> map = %{:foo => "bar", "hello" => :world}
%{:foo => "bar", "hello" => :world}
iex> map[:foo]
"bar"
iex> map["hello"]
:world
Από την έκδοση 1.2 της Elixir και μετά, οι μεταβλητές επιτρέπονται σαν κλειδιά χαρτών:
iex> key = "hello"
"hello"
iex> %{key => "world"}
%{"hello" => "world"}
Αν προστεθεί ένα διπλότυπο σε ένα χάρτη, θα αντικαταστήσει την προγενέστερη τιμή:
iex> %{:foo => "bar", :foo => "hello world"}
%{foo: "hello world"}
Όπως μπορούμε να δούμε από την έξοδο από πάνω, υπάρχει ένα ειδικό συντακτικό για χάρτες που περιλαμβάνουν μόνο άτομα σαν κλειδιά:
iex> %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> %{foo: "bar", hello: "world"} == %{:foo => "bar", :hello => "world"}
true
Επιπρόσθετα, υπάρχει ειδικό συντακτικό για την πρόσβαση των κλειδιών που είναι άτομα:
iex> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> map.hello
"world"
Μια άλλη ενδιαφέρουσα ιδιότητα των χαρτών είναι ότι παρέχουν το δικό τους συντακτικό για τις αλλαγές (σημείωση: αυτό δημιουργεί ένα νέο χάρτη):
iex> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> %{map | foo: "baz"}
%{foo: "baz", hello: "world"}
Σημείωση: Αυτό το συντακτικό λειτουργεί μόνο στην αναβάθμιση ενός κλειδιού που υπάρχει ήδη στο χάρτη! Αν το κλειδί δεν υπάρχει, θα σηκωθεί ένα KeyError
.
Αντίθετα, για να δημιουργήσετε ένα νέο κλειδί χρησιμοποιήστε την Map.put/3
iex> map = %{hello: "world"}
%{hello: "world"}
iex> %{map | foo: "baz"}
** (KeyError) key :foo not found in: %{hello: "world"}
(stdlib) :maps.update(:foo, "baz", %{hello: "world"})
(stdlib) erl_eval.erl:259: anonymous fn/2 in :erl_eval.expr/5
(stdlib) lists.erl:1263: :lists.foldl/3
iex> Map.put(map, :foo, "baz")
%{foo: "baz", hello: "world"}
Έπιασες λάθος ή θέλεις να συνεισφέρεις στο μάθημα; Επεξεργαστείτε αυτό το μάθημα στο GitHub!