Question 1Quand la fonction de comparaison renvoie une valeur négative, quel élément sort place-t-il en premier ?
Trier et chercher — sort / find / some / every
sort trie un tableau selon une fonction de comparaison, toSorted garde l'original, find et findIndex renvoient un seul résultat. Avec some et every.
Si tu tries une liste avec une boucle for qui échange des éléments, tu dois gérer toi-même les comparaisons et les échanges, à chaque fois. Chercher le seul élément qui remplit une condition mène au même genre de code : une boucle for avec un break pour sortir dès que l'élément est trouvé.
Cet article présente sort, qui réordonne un tableau, et find, qui cherche un élément qui remplit une condition.
Indiquer l'ordre avec une fonction — sort et la fonction de comparaison
Imagine que tu veux afficher une liste de produits du moins cher au plus cher. Une méthode de tableau s'occupe du tri, mais écrire simplement products.sort() ne trie pas par prix, parce que tu ne lui as pas dit quoi comparer.
Tu passes à sort (une méthode qui réordonne les éléments d'un tableau) une fonction de comparaison (une fonction qui reçoit deux éléments et renvoie un nombre). Si on appelle a et b les deux éléments reçus, une valeur de retour négative place a en premier, et une valeur positive place b en premier. Si tu renvoies a.price - b.price, tu obtiens les prix par ordre croissant.
const products = [
{ name: "Souris sans fil", price: 2980 },
{ name: "Batterie externe", price: 4380 },
{ name: "Câble USB-C", price: 980 },
{ name: "Tapis de souris", price: 2980 },
];
// Si la soustraction est négative, a passe devant ; si elle est positive, b passe devant
products.sort((a, b) => a.price - b.price);
console.log(products.map((item) => item.price).join(", ")); // 980, 2980, 2980, 4380
// Vérifie l'ordre des deux produits au même prix
console.log(products[1].name, products[2].name); // Souris sans fil Tapis de souris
// Inverse la soustraction et tu obtiens l'ordre décroissant
products.sort((a, b) => b.price - a.price);
console.log(products[0].name); // Batterie externe
sort ne regarde que le signe du nombre renvoyé : -2000 et -1 sont donc traités de la même façon. Si tu veux aussi contrôler l'ordre des produits au même prix, fais comparer une autre valeur à la fonction de comparaison quand l'écart vaut 0.
Appeler sort sans argument — comparaison par défaut et toSorted
Imagine que tu veux trier un tableau de durées de consultation d'une page, en secondes, du plus court au plus long. Si tu appelles sort() sans fonction de comparaison, le résultat ne suit pas l'ordre numérique : 1180 secondes passe avant 25 secondes.
Sans fonction de comparaison, sort convertit d'abord les éléments en chaînes, puis les compare caractère par caractère. 1180 est traité comme "1180" et 25 comme "25" : l'ordre se décide donc sur le premier caractère, 1 contre 2. sort réordonne sur place le tableau sur lequel il est appelé ; si tu veux aussi garder l'ordre d'origine, utilise toSorted (une méthode qui renvoie un nouveau tableau trié).
const viewSeconds = [1180, 980, 25, 4380];
// Sans fonction de comparaison, les valeurs sont comparées comme des chaînes
console.log(viewSeconds.sort().join(", ")); // 1180, 25, 4380, 980
// Avec une fonction de comparaison, le tri suit l'ordre numérique
console.log(viewSeconds.sort((a, b) => a - b).join(", ")); // 25, 980, 1180, 4380
// toSorted renvoie un nouveau tableau et laisse l'original intact
const stayTimes = [1180, 980, 25, 4380];
console.log(stayTimes.toSorted((a, b) => a - b).join(", ")); // 25, 980, 1180, 4380
console.log(stayTimes.join(", ")); // 1180, 980, 25, 4380
Une fois converti en chaîne, "1180" passera toujours avant "25" : passe donc une fonction de comparaison quand tu tries un tableau de nombres. Le deuxième sort du code ci-dessus trie de nouveau viewSeconds, que le premier appel a déjà réordonné.
sort sur la ligne du haut, c'est viewSeconds lui-même, réordonné. Seul toSorted crée un nouveau tableau.Les anciens navigateurs n'ont pas toSorted
toSorted a été ajouté à la spécification dans ES2023 : dans les anciens navigateurs qui ne le prennent pas en charge, la ligne qui l'appelle lève une TypeError. Pour que ton code marche aussi dans ces environnements, appelle sort sur une copie faite avec la syntaxe de décomposition, comme dans [...stayTimes].sort((a, b) => a - b).
Récupérer le seul élément qui correspond — find et findIndex
Imagine que tu veux récupérer une réservation à partir de son code. Tu pourrais utiliser filter, mais il renvoie un tableau : tu devrais ajouter [0] pour lire le premier élément, et si aucune réservation ne correspond, tu récupères un tableau vide.
find (une méthode qui renvoie le premier élément qui remplit une condition) renvoie l'élément lui-même : le premier pour lequel le callback renvoie true. Si tu veux plutôt sa position, utilise findIndex (une méthode qui renvoie la position du premier élément qui remplit une condition).
const reservations = [
{ code: "RSV-201", room: "Salle de réunion A" },
{ code: "RSV-202", room: "Salle de réunion B" },
{ code: "RSV-203", room: "Salle de réunion C" },
];
// Renvoie le premier élément pour lequel le callback a renvoyé true
const target = reservations.find((item) => item.code === "RSV-202");
console.log(target.room); // Salle de réunion B
// Utilise findIndex quand tu veux la position
console.log(reservations.findIndex((item) => item.code === "RSV-202")); // 1
// Quand aucune réservation ne correspond
console.log(reservations.find((item) => item.code === "RSV-999")); // undefined
console.log(reservations.findIndex((item) => item.code === "RSV-999")); // -1
true pour le 2e élément, il n'est jamais appelé pour le 3e. Plus la correspondance arrive tôt, moins il y a d'appels.find ne renvoie que le premier élément qui correspond : il ne peut donc pas rassembler toutes les correspondances quand il y en a plusieurs. Utilise filter, qui renvoie un tableau, quand tu as besoin de toutes, et find quand une seule suffit.
Tu obtiens undefined quand rien n'est trouvé
Si tu lis directement la valeur renvoyée par find, comme dans target.room, tu obtiens TypeError: Cannot read properties of undefined (reading 'room') quand aucun élément ne correspond. Vérifie-la avec if (target) avant de la lire.
Vérifier tout le tableau par vrai ou faux — some et every
Imagine que tu veux décider, d'après les stocks, si tous les articles d'une commande peuvent partir ensemble. Tu pourrais rassembler les articles en rupture avec filter et les compter, mais ce que tu veux, ce n'est pas un tableau : c'est une seule réponse, true ou false.
some (une méthode qui renvoie true si au moins un élément remplit la condition) et every (une méthode qui renvoie true si tous les éléments remplissent la condition) renvoient un booléen, pas un élément. Tu peux t'en servir directement comme condition d'un if.
const orderItems = [
{ name: "Flacon de recharge", stock: 12 },
{ name: "Savon pour les mains", stock: 0 },
{ name: "Filet moussant", stock: 5 },
];
// true si au moins un élément correspond
console.log(orderItems.some((item) => item.stock === 0)); // true
// true seulement si tous correspondent
console.log(orderItems.every((item) => item.stock > 0)); // false
// Sur un tableau vide, some vaut false et every vaut true
console.log([].some((item) => item.stock > 0)); // false
console.log([].every((item) => item.stock > 0)); // true
some comme every ont leur réponse dès le 2e article, dont le stock vaut 0. every s'arrête dès qu'il trouve un élément qui ne correspond pas.Sur un tableau vide, aucun élément ne remplit la condition, donc some vaut false ; et aucun élément ne l'enfreint non plus, donc every vaut true. Le tableau ci-dessous résume ce que renvoient les 4 méthodes de recherche vues dans cet article.
| Méthode | Renvoie | Si aucun ne correspond |
|---|---|---|
| find | Le premier élément qui correspond | undefined |
| findIndex | L'index du premier qui correspond | -1 |
| some | true si au moins un correspond | false |
| every | true si tous correspondent | false (true pour un tableau vide) |
Vérification des connaissances
Répondez à chaque question une par une.
Question 2Si tu appelles sort() sur [1180, 980, 25] sans fonction de comparaison, quel ordre obtiens-tu ?
Question 3Quelle méthode utilises-tu pour vérifier, avec un seul booléen, que toutes les quantités en stock valent 1 ou plus ?