L'un des objectifs centraux de Julia est de pouvoir effectuer des calculs sur des données numériques, rapidement et efficacement. Beaucoup de données numériques.
En général, ces données sont stockées dans des tableaux (ou dans un type apparenté), ce qui permet de dire que les tableaux sont au cœur du langage Julia.
La taille d'un tableau peut être arbitraire (seules les contraintes de mémoire de ta machine s'appliquent) et il peut avoir un nombre arbitraire de dimensions.
Ce concept d'introduction se concentre sur les bases des tableaux à une dimension, que l'on appelle des vecteurs.
En Julia, un vecteur est une séquence ordonnée de valeurs auxquelles on accède par un indice.
La façon la plus simple de créer un vecteur est de lister les valeurs entre crochets :
julia> num_vec = [1, 4, 9]
3-element Vector{Int64}:
1
4
9
julia> str_vec = ["arrays", "are", "important"]
3-element Vector{String}:
"arrays"
"are"
"important"
Le type du vecteur correspond au type de chaque élément.
Et donc les vecteurs doivent être homogènes (tous les éléments du même type) ?
Dans une certaine mesure, oui, et il est recommandé de viser cela si tu veux les meilleures performances.
Cependant, Julia peut contourner cette limitation (quand c'est nécessaire) en utilisant le type Any :
julia> mixed_vector = [1, "str", 'c']
3-element Vector{Any}:
1
"str"
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
Lorsque l'on crée un vecteur vide, Julia utilise par défaut le type d'élément Any, mais on peut le préciser en annotant le tableau vide avec le type d'élément souhaité.
julia> empty_vec = []
Any[]
julia> empty_int_vec = Int64[]
Int64[]
Lis et retiens bien cette règle :
Cela ne surprendra personne ayant déjà utilisé d'autres langages de data science (R, Matlab, Fortran...), mais peut sembler choquant aux informaticiens venus des langages de la famille du C.
À part cela, les indices fonctionnent comme tu peux l'imaginer : il suffit de les mettre entre crochets :
squares = [0, 1, 4, 9, 16]
squares[1] # 0
squares[3] # 4
squares[begin] # 0 ("begin" is synonym for 1)
squares[end] # 16 ("end" is synonym for length(squares))
Remarque la commodité de l'indexation avec end (très utile) et begin (probablement moins).
Les programmeurs Python se demandent peut-être ce qu'il en est des indices négatifs.
Mauvaise idée : ils ne font pas partie de Julia et déclencheront une BoundsError, comme n'importe quel indice inférieur à 1 ou supérieur à length(squares).
Les vecteurs en Julia sont mutables : on peut modifier le contenu de chaque cellule.
julia> vals = [1, 3, 5, 7]
4-element Vector{Int64}:
1
3
5
7
julia> vals[2] = 4 # reassign the value of this element
4
# Only the value at position 2 changes:
julia> vals
4-element Vector{Int64}:
1
4
5
7
De nombreuses fonctions permettent de manipuler les vecteurs, même si la documentation de Julia les généralise sous le terme de « collections » plutôt que de vecteurs.
Remarque que, par convention, les fonctions qui mutent leur entrée ont un ! dans leur nom.
Le compilateur ne l'imposera pas, mais c'est une convention très forte dans le monde Julia.
Voici quelques-unes des fonctions utiles :
push!().pop!().pushfirst!() et popfirst!().insert!() et deleteat!().julia> vals = [1, 3]
2-element Vector{Int64}:
1
3
julia> push!(vals, 5, 6) # can add multiple values
4-element Vector{Int64}:
1
3
5
6
julia> pop!(vals) # mutates vals, return popped value
6
julia> vals
3-element Vector{Int64}:
1
3
5
En future magicienne, Elyse doit s'entraîner sur quelques bases. Elle a une pile de cartes qu'elle souhaite manipuler.
Pour simplifier un peu les choses, elle n'utilise que les cartes de 1 à 10, ce qui permet de représenter sa pile de cartes par un vecteur de nombres. La position d'une carte donnée correspond à l'indice dans le vecteur.
Pour choisir une carte, renvoie la carte située à l'indice position dans la pile donnée.
julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> get_item(stack, position)
4
Fais un tour de passe-passe et échange la carte située à l'indice position avec la carte de remplacement fournie.
Renvoie la pile modifiée.
julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> replacement_card = 6;
julia> set_item!(stack, position, replacement_card)
[1, 2, 6, 1]
Fais apparaître une carte en insérant une nouvelle carte en haut de la pile. Renvoie la pile modifiée.
julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_top!(stack, new_card)
[5, 9, 7, 1, 8]
Fais disparaître une carte en retirant de la pile la carte située à la position donnée.
Renvoie la pile modifiée.
julia> stack = [3, 2, 6, 4, 8];
julia> position = 3;
julia> remove_item!(stack, position)
[3, 2, 4, 8]
Fais disparaître une carte en retirant la carte du haut de la pile. Renvoie la pile modifiée.
julia> stack = [3, 2, 6, 4, 8];
julia> remove_item_from_top!(stack)
[3, 2, 6, 4]
Fais apparaître une carte en insérant une nouvelle carte en bas de la pile. Renvoie la pile modifiée.
julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_bottom!(stack, new_card)
[8, 5, 9, 7, 1]
Fais disparaître une carte en retirant la carte du bas de la pile. Renvoie la pile modifiée.
julia> stack = [8, 5, 9, 7, 1];
julia> remove_item_at_bottom!(stack)
[5, 9, 7, 1]
Vérifie si la taille de la pile est égale à stack_size ou non.
julia> stack = [3, 2, 6, 4, 8];
julia> stack_size = 4;
julia> check_size_of_stack(stack, stack_size)
false
Inscris-toi sur Exercism pour apprendre et maîtriser Julia avec 35 concepts128 exercices, et un vrai mentorat humain, le tout gratuitement.