Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.
Array : méthode sort()
Baseline Widely available
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.
La méthodesort() des instances deArray trie les éléments d'un tableauen place et retourne la référence vers ce même tableau, désormais trié. L'ordre de tri par défaut est croissant, basé sur la conversion des éléments en chaînes de caractères, puis la comparaison de leurs séquences d'unités de code UTF-16.
La complexité temporelle et spatiale du tri n'est pas garantie, car elle dépend de l'implémentation.
Pour trier les éléments d'un tableau sans modifier le tableau original, utiliseztoSorted().
Dans cet article
Exemple interactif
const months = ["March", "Jan", "Feb", "Dec"];months.sort();console.log(months);// Résultat attendu : Array ["Dec", "Feb", "Jan", "March"]const array = [1, 30, 4, 21, 100000];array.sort();console.log(array);// Résultat attendu : Array [1, 100000, 21, 30, 4]Syntaxe
sort()sort(compareFn)Paramètres
compareFnFacultatifUne fonction qui détermine l'ordre des éléments. La fonction est appelée avec les arguments suivants :
aLe premier élément à comparer. Ne sera jamais
undefined.bLe second élément à comparer. Ne sera jamais
undefined.
Elle doit retourner un nombre où :
- Une valeur négative indique que
adoit précéderb. - Une valeur positive indique que
adoit suivreb. - Zéro ou
NaNindique queaetbsont considérés comme égaux.
Pour s'en souvenir, rappelez-vous que
(a, b) => a - btrie les nombres par ordre croissant.Si ce paramètre est omis, les éléments du tableau sont convertis en chaînes de caractères, puis triés selon la valeur du point de code Unicode de chaque caractère.
Valeur de retour
La référence vers le tableau d'origine, désormais trié. Notez que le tableau est triéen place, aucune copie n'est réalisée.
Description
SicompareFn n'est pas fourni, tous les éléments du tableau qui ne valent pasundefined sont triés en les convertissant en chaînes de caractères et en comparant ces chaînes selon l'ordre des unités de code UTF-16. Par exemple, « banane » sera trié avant « cerise ». Dans un tri numérique, 9 sera trié avant 80, mais comme les nombres sont convertis en chaînes de caractères, « 80 » arrive avant « 9 » selon l'ordre Unicode. Tous les éléments valantundefined sont placés à la fin du tableau.
La méthodesort() préserve les cases vides. Si le tableau source est untableau creux, les cases vides sont déplacées à la fin du tableau, et arrivent toujours après tous lesundefined.
Note :En UTF-16, les caractères Unicode au-dessus de\uFFFF sont encodés avec deux unités de codesurrogates, de l'intervalle\uD800 -\uDFFF. La valeur de chaque unité de code est prise séparément en compte pour la comparaison. Ainsi, le caractère formé par la pairesurrogate\uD855\uDE51 sera trié avant le caractère\uFF3A.
SicompareFn est fourni, tous les éléments du tableau qui ne valent pasundefined sont triés selon la valeur de retour de la fonction de comparaison (tous les élémentsundefined sont placés à la fin du tableau, sans appel àcompareFn).
Valeur de retour decompareFn(a, b) | Ordre de tri |
|---|---|
| > 0 | triea aprèsb, par exemple[b, a] |
| < 0 | triea avantb, par exemple[a, b] |
| === 0 | conserve l'ordre d'origine dea etb |
Ainsi, la fonction de comparaison a la forme suivante :
function compareFn(a, b) { if (a est inférieur à b selon un critère de tri) { return -1; } else if (a est supérieur à b selon le critère de tri) { return 1; } // a doit être égal à b return 0;}Plus formellement, le comparateur doit respecter les propriétés suivantes pour garantir un tri correct :
- Pur : Le comparateur ne modifie pas les objets comparés ni aucun état externe. (Ceci est important car il n'y a aucune garantie surquand etcomment le comparateur sera appelé, donc chaque appel ne doit produire aucun effet visible à l'extérieur.)
- Stable : Le comparateur retourne le même résultat pour la même paire d'entrées.
- Réflexif :
compareFn(a, a) === 0. - Antisymétrique :
compareFn(a, b)etcompareFn(b, a)doivent être tous deux0ou avoir des signes opposés. - Transitif : Si
compareFn(a, b)etcompareFn(b, c)sont tous deux positifs, nuls ou négatifs, alorscompareFn(a, c)a la même positivité que les deux précédents.
Un comparateur respectant les contraintes ci-dessus pourra toujours retourner1,0 et-1, ou retourner systématiquement0. Par exemple, si un comparateur ne retourne que1 et0, ou seulement0 et-1, il ne pourra pas trier correctement car l'antisymétrie est rompue. Un comparateur qui retourne toujours0 ne modifiera pas le tableau, mais reste fiable.
Le comparateur lexicographique par défaut respecte toutes les contraintes ci-dessus.
Pour comparer des nombres plutôt que des chaînes, la fonction de comparaison peut soustraireb àa. La fonction suivante triera le tableau par ordre croissant (si le tableau ne contient pasNaN) :
function compareNombres(a, b) { return a - b;}La méthodesort() estgénérique. Elle attend seulement que la valeur dethis possède une propriétélength et des propriétés à clés entières. Bien que les chaînes de caractères soient aussi assimilables à des tableaux, cette méthode ne doit pas être appliquée sur elles, car les chaînes sont immuables.
Exemples
>Création, affichage et tri d'un tableau
L'exemple suivant crée quatre tableaux et affiche le tableau original, puis les tableaux triés. Les tableaux numériques sont triés sans fonction de comparaison, puis triés avec une fonction de comparaison.
const stringArray = ["Blue", "Humpback", "Beluga"];const numberArray = [40, 1, 5, 200];const numericStringArray = ["80", "9", "700"];const mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];function compareNumbers(a, b) { return a - b;}stringArray.join(); // 'Blue,Humpback,Beluga'stringArray.sort(); // ['Beluga', 'Blue', 'Humpback']numberArray.join(); // '40,1,5,200'numberArray.sort(); // [1, 200, 40, 5]numberArray.sort(compareNumbers); // [1, 5, 40, 200]numericStringArray.join(); // '80,9,700'numericStringArray.sort(); // ['700', '80', '9']numericStringArray.sort(compareNumbers); // ['9', '80', '700']mixedNumericArray.join(); // '80,9,700,40,1,5,200'mixedNumericArray.sort(); // [1, 200, 40, 5, '700', '80', '9']mixedNumericArray.sort(compareNumbers); // [1, 5, '9', 40, '80', 200, '700']Tri d'un tableau d'objets
On peut trier un tableau d'objets en comparant la valeur de l'une de leurs propriétés.
const items = [ { name: "Edward", value: 21 }, { name: "Sharpe", value: 37 }, { name: "And", value: 45 }, { name: "The", value: -12 }, { name: "Magnetic", value: 13 }, { name: "Zeros", value: 37 },];// trier par valeuritems.sort((a, b) => a.value - b.value);// trier par nomitems.sort((a, b) => { const nameA = a.name.toUpperCase(); // ignorer les majuscules/minuscules const nameB = b.name.toUpperCase(); // ignorer les majuscules/minuscules if (nameA < nameB) { return -1; } if (nameA > nameB) { return 1; } // les noms sont égaux return 0;});Tri de chaînes de caractères non ASCII
Pour trier des chaînes contenant des caractères nonASCII, c'est-à-dire des caractères accentués (e, é, è, a, ä, etc.) ou des chaînes dans d'autres langues que l'anglais, utilisezString.prototype.localeCompare(). Cette fonction permet de comparer ces caractères afin qu'ils apparaissent dans le bon ordre.
const items = ["réservé", "premier", "communiqué", "café", "adieu", "éclair"];items.sort((a, b) => a.localeCompare(b));// items vaut ['adieu', 'café', 'communiqué', 'éclair', 'premier', 'réservé']Tri avec map
La fonctioncompareFn peut être appelée plusieurs fois par élément du tableau. Selon la nature decompareFn, cela peut entraîner un surcoût important. Plus la fonction de comparaison est complexe et plus le tableau est grand, plus il peut être efficace d'utilisermap() pour le tri. L'idée est de parcourir le tableau une fois pour extraire les valeurs utilisées pour le tri dans un tableau temporaire, de trier ce tableau temporaire, puis de parcourir ce tableau temporaire pour obtenir l'ordre souhaité.
// le tableau à trierconst data = ["delta", "alpha", "charlie", "bravo"];// le tableau temporaire contient les objets avec la position et la valeur de triconst mapped = data.map((v, i) => ({ i, value: someSlowOperation(v) }));// tri du tableau temporaire contenant les valeurs réduitesmapped.sort((a, b) => { if (a.value > b.value) { return 1; } if (a.value < b.value) { return -1; } return 0;});const result = mapped.map((v) => data[v.i]);Il existe une bibliothèque open source appeléemapsort(angl.) qui applique cette approche.
sort() retourne la référence du même tableau
La méthodesort() retourne une référence vers le tableau d'origine, donc toute modification du tableau retourné modifie également le tableau d'origine.
const numbers = [3, 1, 4, 1, 5];const sorted = numbers.sort((a, b) => a - b);// numbers et sorted valent tous deux [1, 1, 3, 4, 5]sorted[0] = 10;console.log(numbers[0]); // 10Si vous souhaitez quesort() ne modifie pas le tableau d'origine, mais retourne un tableaucopié superficiellement comme d'autres méthodes de tableau (par exemple,map()), utilisez la méthodetoSorted(). Vous pouvez aussi faire une copie superficielle avant d'appelersort(), en utilisant lasyntaxe de l'opérateur de propagation ouArray.from().
const numbers = [3, 1, 4, 1, 5];// [...numbers] crée une copie superficielle, donc sort() ne modifie pas l'originalconst sorted = [...numbers].sort((a, b) => a - b);sorted[0] = 10;console.log(numbers[0]); // 3Stabilité du tri
Depuis la version 10 (ou ECMAScript 2019), la spécification impose queArray.prototype.sort soit stable.
Par exemple, supposons que vous ayez une liste d'élèves avec leurs notes. Notez que la liste d'élèves est déjà pré-triée par nom par ordre alphabétique :
const students = [ { name: "Alex", grade: 15 }, { name: "Devlin", grade: 15 }, { name: "Eagle", grade: 13 }, { name: "Sam", grade: 14 },];Après avoir trié ce tableau par la propriétégrade par ordre croissant :
students.sort((firstItem, secondItem) => firstItem.grade - secondItem.grade);La variablestudents aura alors la valeur suivante :
[ { name: "Eagle", grade: 13 }, { name: "Sam", grade: 14 }, { name: "Alex", grade: 15 }, // ordre d'origine conservé pour les mêmes notes (tri stable) { name: "Devlin", grade: 15 }, // ordre d'origine conservé pour les mêmes notes (tri stable)];Il est important de noter que les élèves ayant la même note (par exemple, Alex et Devlin) restent dans le même ordre qu'avant l'appel à sort. C'est ce que garantit un algorithme de tri stable.
Avant la version 10 (ou ECMAScript 2019), la stabilité du tri n'était pas garantie, ce qui pouvait donner :
[ { name: "Eagle", grade: 13 }, { name: "Sam", grade: 14 }, { name: "Devlin", grade: 15 }, // ordre d'origine non conservé { name: "Alex", grade: 15 }, // ordre d'origine non conservé];Tri avec un comparateur mal formé
Si une fonction de comparaison ne respecte pas toutes les règles de pureté, stabilité, réflexivité, antisymétrie et transitivité, comme expliqué dans ladescription, le comportement du programme n'est pas défini.
Par exemple :
const arr = [3, 1, 4, 1, 5, 9];const compareFn = (a, b) => (a > b ? 1 : 0);arr.sort(compareFn);La fonctioncompareFn ici n'est pas bien formée, car elle ne respecte pas l'antisymétrie : sia > b, elle retourne1 ; mais en inversanta etb, elle retourne0 au lieu d'une valeur négative. Ainsi, le tableau résultant sera différent selon les moteurs JavaScript. Par exemple, V8 (utilisé par Chrome, Node.js, etc.) et JavaScriptCore (utilisé par Safari) ne trieront pas le tableau et retourneront[3, 1, 4, 1, 5, 9], tandis que SpiderMonkey (utilisé par Firefox) retournera le tableau trié par ordre croissant, soit[1, 1, 3, 4, 5, 9].
Cependant, si la fonctioncompareFn est modifiée pour retourner-1 ou0 :
const arr = [3, 1, 4, 1, 5, 9];const compareFn = (a, b) => (a > b ? -1 : 0);arr.sort(compareFn);V8 et JavaScriptCore le trient alors par ordre décroissant, comme[9, 5, 4, 3, 1, 1], tandis que SpiderMonkey le retourne tel quel :[3, 1, 4, 1, 5, 9].
En raison de cette incohérence d'implémentation, il est toujours conseillé de s'assurer que votre comparateur est bien formé en respectant les cinq contraintes.
Utilisation desort() sur des tableaux creux
Les cases vides sont déplacées à la fin du tableau.
console.log(["a", "c", , "b"].sort()); // ['a', 'b', 'c', empty]console.log([, undefined, "a", "b"].sort()); // ["a", "b", undefined, empty]Appel desort() sur des objets qui ne sont pas des tableaux
La méthodesort() lit la propriétélength dethis. Elle collecte ensuite toutes les propriétés à clé entière existantes dans l'intervalle de0 àlength - 1, les trie, puis les réécrit. S'il manque des propriétés dans l'intervalle, les propriétés finales correspondantes sontsupprimées, comme si les propriétés inexistantes étaient triées vers la fin.
const objetSimilaireTableau = { length: 3, unrelated: "foo", 0: 5, 2: 4,};console.log(Array.prototype.sort.call(objetSimilaireTableau));// { '0': 4, '1': 5, length: 3, unrelated: 'foo' }Spécifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-array.prototype.sort> |
Compatibilité des navigateurs
Voir aussi
- Guide des collections indexées
- L'objet global
Array - La méthode
Array.prototype.reverse() - La méthode
Array.prototype.toSorted() - La méthode
String.prototype.localeCompare() - La méthode
TypedArray.prototype.sort() - Prothèse d'émulation de
Array.prototype.sortavec un comportement moderne (tri stable) dans core-js(angl.) - Getting things sorted in V8(angl.) sur v8.dev (2018)
- Tri stable de
Array.prototype.sort(angl.) sur v8.dev (2019) - Stabilité de
Array.prototype.sort(angl.) par Mathias Bynens