JavaScript dispose d'un opérateur ... intégré qui facilite le travail avec un nombre indéfini d'éléments. Selon le contexte, on l'appelle soit rest operator, soit spread operator.
Quand ... apparaît du côté gauche d'une affectation, ces trois points sont appelés l'opérateur rest. Les trois points accompagnés d'un nom de variable forment ce qu'on appelle un élément rest. Il collecte zéro ou plusieurs valeurs et les stocke dans un seul tableau.
const [a, b, ...everythingElse] = [0, 1, 1, 2, 3, 5, 8];
a;
// => 0
b;
// => 1
everythingElse;
// => [1, 2, 3, 5, 8]
À noter qu'en JavaScript, contrairement à certains autres langages, un élément rest ne peut pas être suivi d'une virgule finale. Il doit être le dernier élément d'une affectation par déstructuration. L'exemple ci-dessous lève une SyntaxError :
const [...items, last] = [2, 4, 8, 16]
Comme pour les tableaux, l'opérateur rest peut aussi servir à collecter une ou plusieurs propriétés d'un objet et à les stocker dans un seul objet.
const { street, ...address } = {
street: 'Platz der Republik 1',
postalCode: '11011',
city: 'Berlin',
};
street;
// => 'Platz der Republik 1'
address;
// => {postalCode: '11011', city: 'Berlin'}
Quand ... apparaît dans la définition d'une fonction, à côté de son dernier argument, ce paramètre est appelé rest parameter. Il permet à la fonction d'accepter un nombre indéfini d'arguments sous forme de tableau.
function concat(...strings) {
return strings.join(' ');
}
concat('one');
// => 'one'
concat('one', 'two', 'three');
// => 'one two three'
Quand ... apparaît du côté droit d'une affectation, on l'appelle l'opérateur spread. Il déploie un tableau en une liste d'éléments. Contrairement à l'élément rest, il peut apparaître n'importe où dans une expression littérale de tableau, et il peut y en avoir plusieurs.
const oneToFive = [1, 2, 3, 4, 5];
const oneToTen = [...oneToFive, 6, 7, 8, 9, 10];
oneToTen;
// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const woow = ['A', ...oneToFive, 'B', 'C', 'D', 'E', ...oneToFive, 42];
woow;
// => ["A", 1, 2, 3, 4, 5, "B", "C", "D", "E", 1, 2, 3, 4, 5, 42]
Comme pour les tableaux, l'opérateur spread peut aussi servir à copier les propriétés d'un objet vers un autre.
let address = {
postalCode: '11011',
city: 'Berlin',
};
address = { ...address, country: 'Germany' };
// => {
// postalCode: '11011',
// city: 'Berlin',
// country: 'Germany',
// }
Ton ami Linus est conducteur de train : il conduit des trains de marchandises entre les villes. Même s'il est incroyable quand il s'agit de conduire un train, il l'est beaucoup moins en logistique et en informatique. Il aimerait faire appel à tes talents de programmeur pour organiser les détails des trains et corriger les erreurs dans les données d'itinéraires.
Pour t'entraîner, utilise l'opérateur de reste ou de décomposition pour résoudre chacune des tâches ci-dessous.
Ton ami a noté l'identifiant (ID) de chaque wagon, mais il n'est jamais sûr du nombre de wagons que le système devra traiter à un moment donné.
Ce serait beaucoup plus simple pour le reste du programme de logistique si ces données étaient regroupées dans un array unique.
Implémente une fonction getListOfWagons qui accepte un nombre arbitraire d'identifiants de wagons, chacun étant l'ID d'un wagon.
Chaque ID sera un entier positif.
La fonction doit ensuite renvoyer les IDs donnés sous la forme d'un array unique.
getListOfWagons(1, 7, 12, 3, 14, 8, 5);
// => [1, 7, 12, 3, 14, 8, 5]
À ce stade, tu commences à te familiariser avec les données et avec la façon dont elles sont utilisées dans le programme de logistique. Le système d'ID attribue toujours l'ID 1 à la locomotive, le reste des wagons du train recevant un ID choisi au hasard, supérieur à 1.
Ton ami a dû accrocher deux nouveaux wagons au train et a oublié de mettre à jour le système !
Maintenant, les deux premiers wagons du array du train doivent être déplacés à la fin, sinon tout sera dans le désordre.
Linus te serait vraiment reconnaissant de corriger ses erreurs.
Implémente une fonction fixListOfWagons qui prend un tableau contenant l'ID de chaque wagon.
Elle return un array dans lequel les 2 premiers éléments ont été déplacés à la fin du array, afin que la locomotive se retrouve en tête.
eachWagonsID = [2, 5, 1, 7, 4, 12, 6, 3, 13];
fixListOfWagons(eachWagonsID);
// => [1, 7, 4, 12, 6, 3, 13, 2, 5]
Aïe. On dirait que des wagons ont disparu.
Heureusement, ton ami vient de trouver un autre array qui semble contenir les IDs des wagons manquants, et il aimerait que tu les ajoutes au array principal des IDs de wagons.
Tout ce dont il se souvient, c'est que les valeurs manquantes doivent être placées juste après la locomotive désignée.
Avec ces nouvelles informations, écris une fonction appelée correctListOfWagons qui prend en arguments deux tableaux contenant les IDs de chaque wagon.
Les IDs de wagons du second array doivent être ajoutés dans le premier array, juste après la locomotive (ID 1).
eachWagonsID = [1, 5, 20, 7, 4, 8];
missingWagons = [3, 17, 6, 15];
correctListOfWagons(eachWagonsID, missingWagons);
// => [1, 3, 17, 6, 15, 5, 20, 7, 4, 8]
Maintenant que toutes les données des wagons sont correctes, ton ami aimerait que tu mettes à jour les informations d'itinéraire du système.
Les informations d'itinéraire initiales ont été construites sous la forme d'un object, et ton ami aimerait que tu les mettes à jour avec les ajouts fournis.
Chaque itinéraire demande des informations légèrement différentes, c'est pourquoi ton ami préférerait vraiment une solution générique.
Implémente une fonction extendRouteInformation qui prend deux objects.
Le premier object contient les villes entre lesquelles circule le train.
Le second object contient d'autres détails d'itinéraire, comme la vitesse ou la longueur du train.
La fonction doit renvoyer un object consolidé contenant toutes les informations d'itinéraire.
La variable moreRouteInformation peut contenir différentes propriétés.
route = { from: 'Berlin', to: 'Hamburg' };
moreRouteInformation = { length: '100', speed: '50' };
extendRouteInformation(route, moreRouteInformation);
// => {from: "Berlin", to: "Hamburg", length: "100", speed: "50"}
Ton ami a remarqué qu'il n'a pas besoin de l'heure d'arrivée dans les informations d'itinéraire. Il aimerait donc que tu sépares l'heure d'arrivée des informations d'itinéraire.
Implémente une fonction separateTimeOfArrival qui prend un objet contenant les informations d'itinéraire.
La fonction doit renvoyer un tableau dont le premier élément est l'heure d'arrivée et le second un objet contenant les informations d'itinéraire sans l'heure d'arrivée.
routeInformation = {
from: 'Berlin',
to: 'Hamburg',
length: '100',
timeOfArrival: '10:10',
};
separateTimeOfArrival(routeInformation);
// => ["10:10", {from: "Berlin", to: "Hamburg", length: "100"}]
Inscris-toi sur Exercism pour apprendre et maîtriser JavaScript avec 37 concepts159 exercices, et un vrai mentorat humain, le tout gratuitement.