325 votes

Trier un tableau d'objets par clé unique avec valeur de date

J'ai un tableau d'objets avec plusieurs paires clé-valeur, et j'ai besoin de les trier sur la base de "updated_at" :

[
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
]

Quelle est la manière la plus efficace de le faire ?

425voto

Rocket Hazmat Points 87407

Vous pouvez utiliser Array.sort .

Voici un exemple :

var arr = [{
    "updated_at": "2012-01-01T06:25:24Z",
    "foo": "bar"
  },
  {
    "updated_at": "2012-01-09T11:25:13Z",
    "foo": "bar"
  },
  {
    "updated_at": "2012-01-05T04:13:24Z",
    "foo": "bar"
  }
]

arr.sort(function(a, b) {
  var keyA = new Date(a.updated_at),
    keyB = new Date(b.updated_at);
  // Compare the 2 dates
  if (keyA < keyB) return -1;
  if (keyA > keyB) return 1;
  return 0;
});

console.log(arr);

179voto

J'ai déjà répondu à une question très similaire ici : Fonction simple pour trier un tableau d'objets

Pour cette question, j'ai créé cette petite fonction qui pourrait faire ce que vous voulez :

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var x = a[key]; var y = b[key];
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}

53voto

Le site Array.sort() trie les éléments d'un tableau en place et retourne le tableau. Faites attention avec Array.sort() car ce n'est pas Immuable . Pour un tri immuable, utilisez tri immuable .

Cette méthode permet de trier le tableau en utilisant la méthode actuelle de updated_at au format ISO. Nous utilisons new Data(iso_string).getTime() pour convertir le temps ISO en timestamp Unix. Un timestamp Unix est un nombre sur lequel nous pouvons faire des calculs simples. Nous soustrayons le premier et le second horodatage et le résultat est : si le premier horodatage est plus grand que le second, le nombre de retour sera positif. Si le deuxième chiffre est plus grand que le premier, la valeur de retour sera négative. Si les deux sont identiques, le retour sera de zéro. Cela correspond parfaitement aux valeurs de retour requises pour la fonction en ligne.

Pour ES6 :

arr.sort((a,b) => new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime());

Pour ES5 :

arr.sort(function(a,b){ 
 return new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime();
});

Si vous changez votre updated_at pour être des timestamps unix vous pouvez faire ceci :

Pour ES6 :

arr.sort((a,b) => a.updated_at - b.updated_at);

Pour ES5 :

arr.sort(function(a,b){ 
 return a.updated_at - b.updated_at;
});

Au moment de la rédaction de cet article, les navigateurs modernes ne prennent pas en charge ES6. Pour utiliser ES6 dans les navigateurs modernes, utilisez babel pour transposer le code en ES5. Attendez-vous à ce que le navigateur prenne en charge ES6 dans un avenir proche.

Array.sort() doit recevoir une valeur de retour correspondant à l'un des trois résultats possibles :

  • Un nombre positif (premier élément > deuxième élément)
  • Un nombre négatif (premier élément < deuxième élément)
  • 0 si les deux éléments sont égaux

Notez que la valeur de retour de la fonction en ligne peut être un nombre positif ou négatif. nombre positif ou négatif. Array.Sort() ne se soucie pas de la valeur de retour. nombre de retour. Elle se soucie uniquement de savoir si la valeur de retour est positive, négative ou nulle.

Pour un tri immuable : (exemple en ES6)

const sort = require('immutable-sort');
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);

Vous pouvez aussi l'écrire de cette façon :

import sort from 'immutable-sort';
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);

L'import-from que vous voyez est une nouvelle façon d'inclure javascript dans ES6 et rend votre code très propre. Mon préféré.

Le tri immuable ne modifie pas le tableau source mais renvoie un nouveau tableau. Utilisation de const est recommandé sur les données immuables.

22voto

Brad Parks Points 5513

Voici une version légèrement modifiée de Réponse de @David Brainer-Bankers qui effectue un tri alphabétique par chaîne de caractères, ou numérique par nombre, et qui garantit que les mots commençant par une majuscule ne sont pas triés au-dessus des mots commençant par une minuscule (par exemple, "apple,Early" seraient affichés dans cet ordre).

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var x = a[key];
        var y = b[key];

        if (typeof x == "string")
        {
            x = (""+x).toLowerCase(); 
        }
        if (typeof y == "string")
        {
            y = (""+y).toLowerCase();
        }

        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}

17voto

Mohammed Safeer Points 1533

Utilisez underscore js ou lodash,

var arrObj = [
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
];

arrObj = _.sortBy(arrObj,"updated_at");

_.sortBy() renvoie un nouveau tableau

se référer à http://underscorejs.org/#sortBy et docs lodash https://lodash.com/docs#sortBy

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