Una Tuple è molto simile a un Vector (un array monodimensionale) sotto molti aspetti.
Tuttavia, ci sono alcune differenze importanti.
( ) invece che tra parentesi quadre [ ], anche se le parentesi tonde si possono omettere nei casi in cui il significato è inequivocabile.L'immutabilità consente al compilatore più ottimizzazioni e rende le tuple più performanti degli array, quindi è preferibile usarle quando la mutabilità non è necessaria.
julia> t = (3, 5.2, "xyz")
(3, 5.2, "xyz")
# Non-homogeneous:
julia> dump(t)
Tuple{Int64, Float64, String}
1: Int64 3
2: Float64 5.2
3: String "xyz"
julia> t[2]
5.2
# Immutable:
julia> t[2] = 7.3
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Float64, String})
Esiste anche un costruttore Tuple(), che trasforma qualsiasi collezione iterabile in una tupla.
Utile a sapersi: tratta una stringa come una collezione iterabile di caratteri.
julia> Tuple("Julia")
('J', 'u', 'l', 'i', 'a')
Per qualsiasi tupla, è possibile accedere agli elementi tramite l'indice o iterare su di essi.
Qualsiasi tupla puramente numerica può anche essere usata nelle funzioni matematiche come sum(), esattamente come gli array.
Una tupla può essere scomposta nei singoli elementi usando l'assegnazione multipla.
Per gli elementi che non servono, usa il trattino basso _ come variabile fittizia.
julia> tup = (1, "Julia", true)
(1, "Julia", true)
julia> num, name, _ = tup
(1, "Julia", true)
julia> uppercase(name), 2num
("JULIA", 2)
Chi programma in Python ha sicuramente familiarità con questa sintassi di assegnazione multipla.
Una Tuple contiene solo valori.
Una NamedTuple associa ogni valore a un nome.
I singoli campi si possono poi accedere con la notazione «punto»:
julia> nt = (a = 1, b = 7.3)
(a = 1, b = 7.3)
julia> dump(nt)
@NamedTuple{a::Int64, b::Float64}
a: Int64 1
b: Float64 7.3
julia> nt.b
7.3
Il nome è memorizzato internamente come Symbol (un tipo immutabile, preceduto da due punti :), quindi è disponibile una sintassi alternativa:
julia> nt[:b]
7.3
È facile ottenere separatamente sia i nomi (chiamati anche «chiavi») sia i valori:
julia> nt
(a = 1, b = 7.3)
julia> keys(nt)
(:a, :b)
julia> values(nt)
(1, 7.3)
Nota che l'iterazione su una tupla con nome produce solo i valori, mentre i nomi vengono ignorati.
Le tuple (con nome o meno) sono un modo molto comune per trasferire dati strutturati da e verso le funzioni. L'immutabilità è un vantaggio in questo caso d'uso, perché garantisce la sicurezza dei dati e consente ottimizzazioni più aggressive da parte del compilatore.
Azara e Rui sono compagni di squadra che partecipano a una caccia al tesoro a tema pirata. Uno ha una lista di tesori con le coordinate sulla mappa, l'altro una lista di nomi di luoghi con le coordinate sulla mappa. Hanno ricevuto anche delle mappe vuote con il punto di partenza contrassegnato da SEI QUI.
| Lista di Azara | Lista di Rui | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
Ma le cose sono un po' disorganizzate: le coordinate di Azara sembrano formattate e ordinate in modo diverso da quelle di Rui, e devono continuare a passare da una lista all'altra per capire quali tesori vanno con quali luoghi. Essendo programmatori Julia in erba, si sono rivolti a te per un aiuto nello scrivere un piccolo programma (in realtà un insieme di funzioni) per organizzare meglio le informazioni della loro caccia.
Implementa la funzione get_cooordinate() che prende una coppia (treasure, coordinate) dalla lista di Azara e restituisce solo la coordinata della mappa estratta.
julia> get_cooordinate( ("Scrimshaw Whale's Tooth", "2A") )
"2A"
Implementa la funzione convert_coordinate() che prende una coordinata nel formato «2A» e restituisce una tupla nel formato ('2', 'A').
julia> convert_coordinate("2A")
('2', 'A')
Implementa la funzione compare_records() che prende una coppia (treasure, coordinate) e un record (location, coordinate, quadrant) e confronta le coordinate di ciascuno.
Restituisci true se le coordinate «corrispondono», e restituisci false se non corrispondono.
Riformatta le coordinate come serve per un confronto accurato.
julia> compare_records(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "blue"))
false
julia> compare_records(("Model Ship in Large Bottle", "8A"), ("Harbor Managers Office", ('8', 'A'), "purple"))
true
Implementa la funzione create_record() che prende una coppia (treasure, coordinate) dalla lista di Azara e un record (location, coordinate, quadrant) dalla lista di Rui e restituisce (coordinate, location, quadrant, treasure) se le coordinate corrispondono.
Se le coordinate non corrispondono, restituisci una tupla vuota. Riformatta le coordinate come serve per un confronto accurato.
julia> create_record(("Brass Spyglass", "4B"), ("Abandoned Lighthouse", ('4', 'B'), "Blue"))
("4B", "Abandoned Lighthouse", "Blue", "Brass Spyglass")
julia> create_record(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "Blue"))
()
Iscriviti a Exercism per imparare e padroneggiare Julia con 35 concetti128 esercizi e il mentoring di persone reali, tutto gratis.