Un Tuple est assez proche d'un Vector (un array à 1 dimension) à bien des égards. Il y a toutefois quelques différences importantes.
( ) plutôt qu'avec des crochets [ ], même si les parenthèses peuvent être omises quand le sens est sans ambiguïté.L'immuabilité permet davantage d'optimisations du compilateur et rend les tuples plus performants que les vecteurs, il faut donc les préférer quand la mutabilité n'est pas nécessaire.
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})
Il existe aussi un constructeur Tuple(), qui transforme n'importe quelle collection itérable en tuple. C'est pratique : il traite une string comme une collection itérable de caractères.
julia> Tuple("Julia")
('J', 'u', 'l', 'i', 'a')
Pour n'importe quel tuple, on peut accéder aux éléments par leur indice ou les parcourir avec une boucle.
Tout tuple purement numérique peut aussi être utilisé dans des fonctions mathématiques comme sum(), exactement comme les tableaux.
On peut déballer un tuple en éléments individuels grâce à l'affectation multiple. Pour les éléments dont on n'a pas besoin, on utilise un tiret bas _ comme variable factice.
julia> tup = (1, "Julia", true)
(1, "Julia", true)
julia> num, name, _ = tup
(1, "Julia", true)
julia> uppercase(name), 2num
("JULIA", 2)
Les développeurs Python connaissent très bien cette syntaxe d'affectation multiple.
Un Tuple ne contient que des valeurs. Un NamedTuple associe chaque valeur à un nom.
On peut alors accéder aux différents champs avec la « notation par point » :
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
Le nom est stocké en interne sous la forme d'un Symbol (un type immuable, précédé d'un deux-points :), une syntaxe alternative est donc disponible :
julia> nt[:b]
7.3
Il est facile d'obtenir séparément les noms (aussi appelés « clés ») ou les valeurs :
julia> nt
(a = 1, b = 7.3)
julia> keys(nt)
(:a, :b)
julia> values(nt)
(1, 7.3)
À noter que parcourir un tuple nommé ne produit que les valeurs, et que les noms sont ignorés.
Les tuples (nommés ou non) sont un moyen très courant de transférer des données structurées vers et depuis des fonctions. L'immuabilité est ici un atout : elle assure la sécurité des données et permet des optimisations du compilateur plus poussées.
Azara et Rui sont coéquipiers dans une chasse au trésor sur le thème des pirates. L'un a une liste de trésors avec leurs coordonnées sur la carte, l'autre une liste de noms de lieux avec leurs coordonnées. Ils ont aussi reçu des cartes vierges avec un point de départ marqué TU ES ICI.
| Liste d'Azara | Liste de Rui | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
Mais tout est un peu désorganisé : les coordonnées d'Azara semblent formatées et triées différemment de celles de Rui, et ils doivent sans cesse passer d'une liste à l'autre pour déterminer quels trésors correspondent à quels lieux. En programmeurs Julia en herbe, ils font appel à toi pour écrire un petit programme (un ensemble de fonctions, en fait) afin de mieux organiser les informations de leur chasse.
Implémente la fonction get_cooordinate() qui prend une paire (treasure, coordinate) de la liste d'Azara et renvoie uniquement la coordonnée extraite de la carte.
julia> get_cooordinate( ("Scrimshaw Whale's Tooth", "2A") )
"2A"
Implémente la fonction convert_coordinate() qui prend une coordonnée au format « 2A » et renvoie un tuple au format ('2', 'A').
julia> convert_coordinate("2A")
('2', 'A')
Implémente la fonction compare_records() qui prend une paire (treasure, coordinate) et un enregistrement (location, coordinate, quadrant) et compare les coordonnées de chacun.
Renvoie true si les coordonnées correspondent, et renvoie false si ce n'est pas le cas.
Reformate les coordonnées si nécessaire pour une comparaison exacte.
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
Implémente la fonction create_record() qui prend une paire (treasure, coordinate) de la liste d'Azara et un enregistrement (location, coordinate, quadrant) de la liste de Rui et renvoie (coordinate, location, quadrant, treasure) si les coordonnées correspondent.
Si les coordonnées ne correspondent pas, renvoie un tuple vide. Reformate les coordonnées si nécessaire pour une comparaison exacte.
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"))
()
Inscris-toi sur Exercism pour apprendre et maîtriser Julia avec 35 concepts128 exercices, et un vrai mentorat humain, le tout gratuitement.