Le tableau est une structure de données mutable qui stocke une collection d'éléments d'un type spécifique. Un tableau est une structure de données indexable. Qu'un tableau soit mutable signifie que si l'on appelle sur lui une méthode qui le modifie, le tableau est modifié. Autrement dit, cela ne crée pas un nouveau tableau, mais modifie celui qui existe déjà.
Pour créer un tableau, on utilise la syntaxe du littéral de tableau ([]), dans laquelle on indique les éléments du tableau séparés par une virgule.
[1, 2, 3] # => [1, 2, 3]
Crystal déduit le type du tableau à partir de ses éléments.
[1, 2, 3].class # => Array(Int32)
Même si l'on a vu plus haut qu'un tableau est une collection d'éléments d'un type spécifique, on peut créer un tableau comportant plusieurs types grâce aux types union. Cela permet au tableau de contenir des éléments de n'importe lequel des types indiqués dans le type union. Crystal déduit le type du tableau à partir de ses éléments.
[1, "2", 3.0] # => [1, "2", 3.0]
[1, "2", 3.0].class # => Array(Int32 | Float64 | String)
Un tableau multidimensionnel est un tableau de tableaux.
Cela signifie que chaque élément du tableau est lui-même un tableau.
C'est utile lorsqu'on souhaite stocker des données sous forme de table.
Pour définir un tableau multidimensionnel, on peut soit écrire un littéral de tableau de tableaux, soit utiliser le constructeur Array.new.
[[1, 2], [3, 4]] # => [[1, 2], [3, 4]]
numbers = Array(Array(Int32)).new() # => []
numbers << [1, 2] # => [[1, 2]]
Pour ajouter un élément à un tableau, on utilise l'opérateur << (append).
[1, 2, 3] << 4 # => [1, 2, 3, 4]
Le type de l'élément que l'on veut ajouter doit être le même que celui du tableau, sinon une erreur est levée.
numbers : Array(Int32 | Float64) = [1, 2, 3]
numbers << 4.0
numbers # => [1, 2, 3, 4.0]
numbers << "5" # => Error: no overload matches 'Array(Int32 | Float64)#<<' with type String
Comme avec String, on peut obtenir la taille d'un tableau grâce à la méthode size.
[1, 2, 3].size # => 3
Le compilateur ne peut pas déduire le type d'un tableau lorsqu'on crée un tableau vide.
Il faut donc préciser le type du tableau.
Pour cela, on peut soit indiquer le type du tableau à l'aide du mot-clé of, soit utiliser la syntaxe d'initialisation de tableau, à savoir Array(T).new.
[] of (Int32 | Float64 | String) # => []
Array(Int32 | Float64 | String).new # => []
Comme avec String, on peut accéder aux éléments d'un tableau grâce à l'opérateur [] (index) en lui donnant l'indice de l'élément auquel on veut accéder.
Si l'indice est hors limites, une IndexError est levée.
[1, 2, 3][0] # => 1
[1, 2, 3][3] # => Index out of bounds (IndexError)
Il est aussi possible d'accéder aux éléments à l'aide d'un intervalle.
[1, 2, 3][0..1] # => [1, 2]
Pour créer un tableau à partir d'un intervalle, on utilise la méthode to_a.
C'est utile lorsqu'on veut créer un tableau de nombres.
(1..3).to_a # => [1, 2, 3]
Pour créer un tableau à partir d'une string, on utilise la méthode split.
Elle permet de découper une string en un tableau de strings à l'aide d'un séparateur.
"1,2,3".split(",") # => ["1", "2", "3"]
Il est aussi possible d'obtenir un tableau de caractères à partir d'une string grâce à la méthode chars.
"123".chars # => ['1', '2', '3']
Pour convertir un tableau de Char ou de String en une String, on peut utiliser la méthode join, qui prend un séparateur en argument.
['1', '2', '3'].join(".") # => "1.2.3"
Pour supprimer un élément à la fin d'un tableau, on peut utiliser la méthode pop, qui prend un argument facultatif indiquant combien d'éléments retirer à la fin du tableau.
La méthode renvoie l'élément supprimé.
Si le tableau est vide, une IndexError est levée.
numbers = [1, 2, 3]
numbers.pop # => 3
numbers # => [1, 2]
empty_numbers = [] of Int32
empty_numbers.pop # => Index out of bounds (IndexError)
Pour supprimer l'élément situé à un indice précis d'un tableau, on peut utiliser la méthode delete_at, qui prend en argument l'indice de l'élément à supprimer.
Si le tableau est vide, une IndexError est levée.
numbers = [1, 2, 3]
numbers.delete_at(1) # => 2
numbers # => [1, 3]
empty_numbers = [] of Int32
empty_numbers.delete_at(0) # => Index out of bounds (IndexError)
Pour modifier l'élément situé à un indice précis d'un tableau, on peut utiliser l'opérateur []= (index assign), qui prend en arguments l'indice de l'élément à modifier et la nouvelle valeur.
Si l'indice est hors limites, une IndexError est levée.
numbers = [1, 2, 3]
numbers[1] = 4
numbers # => [1, 4, 3]
numbers[3] = 5 # => Index out of bounds (IndexError)
Dans cet exercice, tu dois implémenter quelques méthodes pour manipuler un tableau de langages de programmation.
Définis la méthode LanguageList.list qui ne prend aucun argument et renvoie un tableau vide de type Array(String).
LanguageList.list()
# => []
Définis la méthode LanguageList.add qui prend 2 arguments (un tableau de langages et un littéral de chaîne contenant un langage).
La méthode doit renvoyer le tableau avec le nouveau langage ajouté à la fin du tableau.
language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
Définis la méthode LanguageList.remove qui prend 1 argument (un tableau de langages).
La méthode doit renvoyer le tableau sans le dernier élément.
On suppose que le tableau aura toujours au moins un élément.
language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
language_list = LanguageList.remove(language_list)
# => ["Crystal"]
Définis la fonction LanguageList.at qui prend 2 arguments (un tableau de langages et un indice).
La méthode doit renvoyer le langage à l'indice n dans le tableau.
On suppose qu'il y aura toujours un langage à cet indice.
language_list = LanguageList.new()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
LanguageList.at(language_list, 1)
# => "Ruby"
Définis la méthode LanguageList.parse qui prend 1 argument (un littéral de chaîne contenant des langages séparés par une virgule).
La méthode doit renvoyer un tableau de langages.
LanguageList.parse("Crystal, Ruby")
# => ["Crystal", "Ruby"]
Inscris-toi sur Exercism pour apprendre et maîtriser Crystal avec 26 concepts142 exercices, et un vrai mentorat humain, le tout gratuitement.