Message vocal du 0654321098
Salut, c'est Joe ! Merci pour l'estimation que tu m'as envoyée. En revanche, elle ne prend pas en compte ma grange. J'ai une grange qui peut contenir mes marchandises. Du coup je ne vais vendre mon blé, mon lait ou ma laine que lorsque la grange dépassera les 500 marchandises, pour faire de la place.
Évidemment les jours où je vais vendre, je ne peux pas m'occuper du reste de la ferme.
Tu penses que c'est compliqué de prendre ça en compte ? Merci beaucoup pour ton aide !
Bon, il va y avoir du boulot !
Alors, allons-y !
Découvrez les collections
Pour mettre en place ces changements, il va nous falloir trouver un endroit dans notre programme où stocker le lait, le blé et la laine. Pour cela, nous allons découvrir les collections !
Les collections en Swift sont un moyen de stocker plusieurs valeurs dans un même objet. Il en existe 3 différentes, chacune correspondant à une logique de stockage différente :
Nom | Mot-clé Swift | Logique |
Tableau | Array | Une liste ordonnée numériquement |
Dictionnaire | Dictionary | Une liste ordonnée par clé |
Ensemble | Set | Un ensemble de valeurs uniques non ordonnées |
Nous allons tout de suite comprendre comment les tableaux nous permettent de créer la grange dans notre programme.
Appréhendez les tableaux
Les tableaux sont donc des listes ordonnées numériquement. Concrètement, ce sont donc des listes organisées par numéro. Par exemple, si on voulait stocker une liste de courses dans un tableau, cela ressemblerait à :
Les éléments sont donc rangés dans un ordre précis. Cet ordre est indiqué par un numéro. On appelle ce numéro l'index.
La syntaxe des tableaux
Voyons un peu ce que ça donne dans le code. Le tableau est un type qui se note Array
. Pour créer un tableau, il suffit d'utiliser les crochets : []
et de noter les éléments séparés par des virgules :
[element1, element2, element3]
OK, et qu'est-ce que je peux mettre dans un tableau ?
Ce que vous voulez ! Des entiers, des décimaux, des chaînes de caractères, d'autres tableaux ! Bref, une collection, comme une variable, ça peut tout stocker. Car un tableau, c'est ni plus ni moins qu'une liste ordonnée de variables.
Vous n'avez qu'à essayer :
["bleu", "blanc", "rouge"]
[2, 4, 8, 16, 32, 64]
Copiez ça dans le Playground ; en cliquant sur le petit œil à droite, vous constaterez que le Playground vous donne des informations détaillées sur le tableau :
0 "bleu"
1 "blanc”
2 "rouge"
C'est bien beau tout ça, mais il y a des contraintes. Souvenez-vous, nos variables en ont aussi : elles ont toujours un type et ne peuvent pas changer de type. C'est la même chose pour les tableaux :
Un tableau qui contenait des
String
ne peut pas ensuite contenir desBool
.On doit toujours connaître le type stocké par le tableau.
Du coup, un tableau ne peut contenir qu'un seul type ! Un
Int
ne peut pas côtoyer unFloat
, par exemple !
Essayez d'écrire ceci :
```swift
["bleu", "blanc", "rouge"] // OK
["bleu", "blanc", "rouge", 12] // ERREUR
Le type tableau
Le type tableau est un type un peu particulier. Contrairement aux autres types que vous connaissez, comme Bool
ou String
, le type tableau est un type qui en contient un autre. Du coup, il se note avec des crochets et le nom du type stocké à l'intérieur comme ceci, par exemple : [Int]
.
Pour déclarer une variable de type tableau qui va contenir des chaînes de caractères, on va donc pouvoir écrire :
var monTableauDeChaineDeCaracteres: [String]
Suivez le cycle de vie d'une variable
Avec la déclaration précédente, si vous essayez d'accéder à la variable monTableauDeChaineDeCaracteres
, Swift va planter.
Mais je lui ai dit que c'était un tableau ! Que veut-il de plus ?
L'initialisation ! Si vous écrivez par exemple :
var i: Int
On ne peut pas accéder à la variable i
! Parce que la variable i
, comme la variable monTableauDeChaineDeCaracteres
, ne contient aucune valeur. On dit qu'elle n'est pas initialisée.
Cela me donne l'occasion de vous expliquer précisément le cycle de vie d'une variable en Swift. Une variable passe par 4 états différents :
Déclaration.
Initialisation.
Modification.
Suppression.
Un schéma vaudra mieux que de longues explications :
À l'étape de déclaration, la variable n'est pas encore initialisée. Donc on ne peut ni la modifier ni accéder à sa valeur, car elle n'en a pas !
Bien souvent, la déclaration et l'initialisation ont lieu en même temps en écrivant ceci :
var i = 0 // Ici le type est déduit
var j: Int = 0 // Ici le type est explicite
Donc si on veut créer un tableau vide, il faut le déclarer puis l'initialiser. Pour cela, on va simplement utiliser les crochets :
var monTableauVide: [Int]
monTableauVide = []
// ou en une ligne
var monTableauVide: [Int] = []
Vous noterez que nous devons préciser le type du tableau, car sa valeur []
ne donne pas suffisamment d'informations sur son type. Si sa valeur avait été [1]
, on aurait pu se passer du type dans la déclaration.
On va voir d'ailleurs tout de suite comment initialiser un tableau vide sans préciser explicitement son type.
Initialisez les types
Il y a quelque chose que nous n’avons pas vu avec les types : on peut les initialiser en utilisant le nom du type suivi de parenthèses. Par exemple :
var s = String() // s contient ""
var i = Int() // i contient 0
var f = Float() // f contient 0.0
var d = Double() // d contient 0.0
var b = Bool() // b contient false
Chaque initialisation renvoie une valeur par défaut. Nous reverrons cela plus en détail avec la programmation orientée objet. Mais sachez en tout cas que vous pouvez initialiser une variable comme ceci.
Du coup, cela fonctionne avec n'importe quel type ! Donc avec nos tableaux aussi. Donc on peut écrire :
var monTableauDeDecimaux: [Float] = []
monTableauDeDecimaux
contient un tableau vide de type Float
.
La grange
La grange de Joe va être un tableau. Elle peut stocker trois types d'éléments différents que nous allons devoir compter : le lait, le blé et la laine.
Au début, nous allons partir du principe que la grange est vide. Donc nous allons décrire la grange comme ceci :
var barn: [Int] = [0, 0, 0]
Le premier 0 représente le nombre de bidons de lait, le 2e le nombre de bottes de blé et le 3e le nombre de pelotes de laine. Vous copiez ce code en haut de notre programme.
Jouons avec les tableaux
Oui je vous connais, parler, ça va 2 minutes. Vous êtes des personnes d'action !
Maintenant que les tableaux sont bien clairs pour vous, il nous reste seulement quelques petites choses à voir.
Accédez et modifiez les données
C'est très simple, on va utiliser l'index ! On va dire au programme : "Donne-moi l'élément qui se trouve à l'index 3". Pour cela, on va continuer à utiliser nos bons vieux crochets, comme ceci :
var notesDeLaClasse: [Int] = [12, 18, 20, 16, 14, 14, 17, 19, 4]
notesDeLaClasse[2] // Le programme renvoie 20 !
Et pour modifier un élément dans un tableau, on va faire quasiment la même chose :
var notesDeLaClasse: [Int] = [12, 18, 20, 16, 14, 14, 17, 19, 4]
// Le troisième élève a triché ! Il mérite un 0...
notesDeLaClasse[2] = 0 // Et voilà ! Fallait pas tricher...
Définissez la mutabilité des tableaux
Tout comme les variables, les tableaux peuvent être constants ou non. On parle de leur mutabilité. Et très simplement, on déclare un tableau modifiable avec var
, et un tableau constant avec let
.
var monTableauModifiable: [Bool] = [true, false, true]
let jeSuisConstant: [Int] = [1, 1, 4]
Prenons 2 minutes pour comprendre ce que veut dire qu'un tableau est constant. Dans un tableau constant :
Les valeurs ne peuvent pas être modifiées.
La taille du tableau ne peut pas être modifiée. Autrement dit, on ne peut ajouter ni supprimer des éléments du tableau.
Ajoutez et supprimez des éléments
Pour ajouter des éléments dans un tableau, il existe deux méthodes :
append
: permet d'ajouter un élément à la fin du tableau.insert
: permet d'ajouter un élément à l'index de son choix.
Par exemple :
var courses = ["oeufs", "lait", "steak"]
courses.append("crème") // ["oeufs", "lait", "steak", "crème"]
courses.insert("beurre", at: 0) // ["beurre", "oeufs", "lait", "steak", "crème"]
À la ligne 2, je rajoute "crème" à la fin du tableau. À la ligne 3, j'insère "beurre" à l'index 0, donc au début du tableau.
À vous de constituer votre liste de courses !
Pour supprimer des éléments, on utilise la méthode remove
comme ceci :
// courses contient ["beurre", "oeufs", "lait", "steak", "crème"]
// En fait, j'ai du beurre dans mon frigo !
courses.remove(at: 0) // courses contient ["oeufs", "lait", "steak", "crème"]
On précise l'index de l'élément que l'on souhaite supprimer dans la méthode remove
.
Comptez les éléments
Très souvent, on va avoir besoin de compter les éléments dans un tableau. Pour cela, on utilise la propriété count
comme ceci :
var mesPoules = ["Rosette", "Lucienne", "Paquerette"]
mesPoules.count // Affiche 3
Parcourez un tableau
Parfois, il peut être utile de parcourir un tableau. C'est-à-dire faire le tour de tous les éléments du tableau. C'est-à-dire faire une boucle à l'intérieur du tableau.
Euh une boucle, ça me dit quelque chose !
Eh oui, on va utiliser une boucle for pour parcourir le tableau. C'est très simple, regardez :
var mesAmis = ["Pierre", "Paul", "Jacques"]
for unAmi in mesAmis {
print("Salut \(unAmi) !")
}
Dans la console, vous verrez :
Salut Pierre ! Salut Paul ! Salut Jacques !
Nous avions vu l'utilisation de la boucle for avec les intervalles. Eh bien, on peut simplement faire la même chose avec les tableaux.
Dans cet exemple, la variable unAmi
contient à chaque tour de boucle un nouvel élément du tableau mesAmis
en suivant l'ordre du tableau. La boucle s'arrête lorsqu'on atteint la fin du tableau.
À vous de jouer
C'est l'heure d'un petit exercice ! Le tableau suivant contient les notes d'une classe pour un devoir.
var notesDeLaClasse = [18, 4, 14, 15, 17, 15, 9, 20, 19, 11, 12, 14]
Fred a rendu sa copie en retard. Il a eu 13. Pouvez-vous ajouter la note de Fred et calculer ensuite la moyenne de la classe ?
La solution :
var notesDeLaClasse = [18, 4, 14, 15, 17, 15, 9, 20, 19, 11, 12, 14]
// On ajoute la note de Fred
notesDeLaClasse.append(13)
// On calcule la somme des notes
var somme = 0
for note in notesDeLaClasse {
somme += note
}
// On calcule la moyenne
var moyenne = somme / notesDeLaClasse.count
La moyenne obtenue est 13 . Pas mal ! J'espère que vous avez eu 20 à l'exercice !
Mettons tout ça en application avec la ferme de Joe.
Tout d'abord, nous allons modifier notre programme pour qu'à chaque jour de travail le résultat du travail de Joe ne soit pas converti en argent, mais ajouté à la grange. Je vous laisse essayer, avant de regarder la solution ci-dessous.
// La grange de Joe : [lait, blé, laine]
var barn = [0, 0, 0]
while money < price {
// Joe nourrit les vaches tous les jours
money -= 4
if numberOfDay % 30 == 1 {
// Joe moissonne
barn[1] += 100
} else if numberOfDay % 30 == 10 || numberOfDay % 30 == 20 {
// Joe tond les moutons
barn[2] += 30
} else {
// Joe trait les vaches
barn[0] += 30
}
// On passe au jour suivant
numberOfDay += 1
}
Maintenant il va falloir vendre quand la grange dépasse les 500 marchandises. Je vous laisse calculer la quantité de marchandises dans la grange chaque jour.
var barnSize = 0
for goods in barn {
barnSize += goods
}
Maintenant nous allons appliquer le protocole : si la grange contient plus de 500 marchandises, nous allons tout vendre.
var i = 5 // i est un entier qui vaut 5
var d = Double(i) // d est un double qui vaut 5.0
// Le prix du voyage
let price = 1499.0
// L'argent de Joe
var money = 0.0
// Le nombre de jours pendant lesquels Joe doit économiser
var numberOfDay = 0
// La grange de Joe : [lait, blé, laine]
var barn = [0, 0, 0]
while money < price {
// Joe nourrit les vaches tous les jours
money -= 4
// On calcule la taille de la grange
var barnSize = 0
for goods in barn {
barnSize += goods
}
if barnSize >= 500 {
// On vend !
money += Double(barn[0]) * 0.50 // Le lait
money += Double(barn[1]) * 0.30 // Le blé
money += Double(barn[2]) * 1 // La laine
// On vide la grange
barn = [0, 0, 0]
} else {
// C'est une journée normale
if numberOfDay % 30 == 1 {
// Joe moissonne
barn[1] += 100
} else if numberOfDay % 30 == 10 || numberOfDay % 30 == 20 {
// Joe tond les moutons
barn[2] += 30
} else {
// Joe trait les vaches
barn[0] += 30
}
}
// On passe au jour suivant
numberOfDay += 1
}
print("Il aura fallu \(numberOfDay) jours à Joe pour économiser \(money) €")
La console affiche désormais :
Il aura fallu 135 jours à Joe pour économiser 1545.0 €
Si vous n'avez pas réussi, aucun souci ! C'était l'un des travaux pratiques les plus difficiles ! N'hésitez pas à reprendre tranquillement le chapitre !
En résumé
Swift propose trois types de collections :
Les tableaux.
Les dictionnaires.
Les ensembles.
Les tableaux sont des listes ordonnées numériquement.
Un tableau ne peut contenir que des valeurs d'un type unique, et ne peut pas en changer. Le type se notant entre crochets :
[Int]
. Il peut être déduit à partir des valeurs du tableau.Les variables évoluent selon un cycle de vie en 4 étapes :
Déclaration : La variable a un nom et un type, et est constante ou non.
Initialisation : La variable a une valeur.
Modification : La valeur de la variable est modifiée.
Suppression : La variable n'existe plus.
On peut initialiser un type en utilisant le nom du type suivi de parenthèses :
Int()
.
Maintenant que vous savez collecter des données avec les tableaux comme des chefs, je vous propose de passer à la suite – les dictionnaires !