301 votes

Tri naturel de chaînes alphanumériques en JavaScript

Je cherche le moyen le plus simple de trier un tableau composé de chiffres, de texte et d'une combinaison de ces éléments.

Par exemple,

'123asd'
'19asd'
'12345asd'
'asd123'
'asd12'

se transforme en

'19asd'
'123asd'
'12345asd'
'asd12'
'asd123'

Elle sera utilisée en combinaison avec la solution pour une autre question que j'ai posée ici .

La fonction de tri en elle-même fonctionne, ce dont j'ai besoin c'est d'une fonction qui puisse dire que '19asd' est plus petit que '123asd'.

J'écris ceci en JavaScript.

Je cherche une fonction pour le tri naturel.

6voto

Julien Points 15

La bibliothèque la plus complète pour gérer cela en 2019 semble être ordre-naturelpar .

import { orderBy } from 'natural-orderby'

const unordered = [
  '123asd',
  '19asd',
  '12345asd',
  'asd123',
  'asd12'
]

const ordered = orderBy(unordered)

// [ '19asd',
//   '123asd',
//   '12345asd',
//   'asd12',
//   'asd123' ]

Il ne prend pas seulement des tableaux de chaînes de caractères, mais il peut aussi trier par la valeur d'une certaine clé dans un tableau d'objets. Il peut également identifier et trier automatiquement les chaînes de devises, les dates, les devises et un tas d'autres choses.

Il est surprenant de constater qu'il ne pèse que 1,6 kB lorsqu'il est compressé.

2voto

Eric Norcross Points 2654

S'appuyer sur Réponse de kennebec et en utilisant le code que Brian Huisman & David koelle créé, voici un prototype de tri modifié pour un tableau d'objets :

//Usage: unsortedArrayOfObjects.alphaNumObjectSort("name");
//Test Case: var unsortedArrayOfObjects = [{name: "a1"}, {name: "a2"}, {name: "a3"}, {name: "a10"}, {name: "a5"}, {name: "a13"}, {name: "a20"}, {name: "a8"}, {name: "8b7uaf5q11"}];
//Sorted: [{name: "8b7uaf5q11"}, {name: "a1"}, {name: "a2"}, {name: "a3"}, {name: "a5"}, {name: "a8"}, {name: "a10"}, {name: "a13"}, {name: "a20"}]

// **Sorts in place**
Array.prototype.alphaNumObjectSort = function(attribute, caseInsensitive) {
  for (var z = 0, t; t = this[z]; z++) {
    this[z].sortArray = new Array();
    var x = 0, y = -1, n = 0, i, j;

    while (i = (j = t[attribute].charAt(x++)).charCodeAt(0)) {
      var m = (i == 46 || (i >=48 && i <= 57));
      if (m !== n) {
        this[z].sortArray[++y] = "";
        n = m;
      }
      this[z].sortArray[y] += j;
    }
  }

  this.sort(function(a, b) {
    for (var x = 0, aa, bb; (aa = a.sortArray[x]) && (bb = b.sortArray[x]); x++) {
      if (caseInsensitive) {
        aa = aa.toLowerCase();
        bb = bb.toLowerCase();
      }
      if (aa !== bb) {
        var c = Number(aa), d = Number(bb);
        if (c == aa && d == bb) {
          return c - d;
        } else {
          return (aa > bb) ? 1 : -1;
        }
      }
    }

    return a.sortArray.length - b.sortArray.length;
  });

  for (var z = 0; z < this.length; z++) {
    // Here we're deleting the unused "sortArray" instead of joining the string parts
    delete this[z]["sortArray"];
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X