web-dev-qa-db-fra.com

Comment trier un tableau d'objets javascript numériquement puis alphabétiquement?

Duplicata possible:
Tri des objets dans un tableau par une valeur de champ en JavaScript

Comment trier un tableau d'objets numériquement (par id) puis alphabétiquement (par nom)?

La méthode actuelle fournit une sortie non valide.

C'est l'objet que j'essaie de trier

var items = [
    {
        "id": 165,
        "name": "a"
    },
    {
        "id": 236,
        "name": "c"
    },
    {
        "id": 376,
        "name": "b"
    },
    {
        "id": 253,
        "name": "f"
    },
    {
        "id": 235,
        "name": "e"
    },
    {
        "id": 24,
        "name": "d"
    },
    {
        "id": 26,
        "name": "d"
    }
]

et la façon dont j'essaye de trier

items.sort(function(a, b) {
    return (a.id - b.id);
}).sort(function(a, b) {
    return (a.name - b.name);
});

voici le jsfiddle.

http://jsfiddle.net/jh4xb/

EDIT: Désolé pour la confusion, j'ai été tellement confus par ce problème pendant un certain temps.

Ce que j'essaie d'accomplir, c'est d'abord de trier par l'ID le plus élevé, puis de trier par ordre alphabétique, à la fin, cela devrait ressembler à:

var items = [
    {
        "id": 376,
        "name": "b"
    },
    {
        "id": 253,
        "name": "f"
    },
    {
        "id": 236,
        "name": "c"
    },
    {
        "id": 235,
        "name": "e"
    },
    {
        "id": 165,
        "name": "a"
    },
    {
        "id": 26,
        "name": "d"
    },
    {
        "id": 24,
        "name": "d"
    }
]
25
Dennis Martinez

Je pense qu'il vaut mieux faire juste avec ...

items.sort(function(a, b) { 
  return a.id - b.id  ||  a.name.localeCompare(b.name);
});

Le deuxième tri annulera fondamentalement le premier, vous devez donc le faire une fois. )

a.id - b.id || a.name.localeCompare(b.name) expression comparera d'abord les ids; seulement s'ils sont égaux, il comparera les noms (et renverra le résultat de cette comparaison).

Si vous devez inverser l'ordre, échangez les positions (b.id - a.id, Etc.) - ou annulez tout simplement:

items.sort(function(a, b) { 
  return - ( a.id - b.id  ||  a.name.localeCompare(b.name) );
});

Voici le JSFiddle (avoir à simplifier un peu les données pour montrer mon point).

47
raina77ow

SI vous voulez dire que vous vouliez les trier par id et si les id correspondent, vous voulez les trier par name alors utilisez ceci:

items.sort(function(a, b) {
    if (a.id !== b.id) {
        return a.id - b.id
    }
    if (a.name === b.name) {
      return 0;
    }
    return a.name > b.name ? 1 : -1;
});

Sinon, votre question n'est pas claire.

5
Jeremy J Starcher

Créez une fonction générale pour le trier comme vous le souhaitez. Vérifiez la fonction dynamicSort ci-dessous

var items = [
{
 "id": 165,
 "name": "a"},
{
 "id": 236,
 "name": "b"},
{
 "id": 376,
 "name": "c"},
{
 "id": 253,
 "name": "d"},
{
 "id": 235,
 "name": "e"},
{
  "id": 24,
  "name": "f"}
];

function dynamicSort(property) {
   return function(a, b) {
       return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
   }
}

items.sort(dynamicSort('name')).sort(dynamicSort('id'));
console.log(items);
items.sort(dynamicSort('id')).sort(dynamicSort('name')); 
console.log(items);  
4
bhb

votre problème est de savoir comment vous triez les lettres.
a.name - b.name

ne fait pas ce que vous pensez. Il ne s'agit pas de les évaluer dans un ordre lexigraphique. remplacez-le par

a.name < b.name ? -1 : 1;

1
BostonJohn

Je ne vois aucune erreur dans Chrome, mais le tri n'est pas correct.

Si je change votre code de tri en ceci:

var firstRun = items.sort(function(a, b) {
    return (a.id - b.id);
});
var secondRun = firstRun.sort(function(a, b) {
    return (a.name - b.name);
});

console.log(secondRun);​

Je pense que le tri est correct. Votre exemple n'a pas vraiment besoin de faire le deuxième tri car chaque numéro (id) est différent. Mais quand je fais b, d et e ont tous un ID de 235, ça se passe très bien.

0
David Hoerster