web-dev-qa-db-fra.com

Javascript trie un tableau d'objets par une propriété booléenne

Voir éditer à la fin pour un problème réel.

Ok, j'ai ce scénario:

a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]

Alors si je fais ça:

a.sort(function(a,b){return !a && b});

Cela me donne ceci:

[false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]

C'est en quelque sorte un tri ... mais pas tout à fait ... :(

Comment trier ce tableau?

MODIFIER:

Si vous vous demandez pourquoi je n'ai pas utilisé juste a.sort (), c'est parce que mon tableau actuel est constitué d'objets, pas un tableau simple comme celui que j'ai publié. Le vrai a des éléments qui ressemblent à [{xx: true}, {xx: false}, ...]

51
PCoelho
a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false];
    
    
    a.sort(function(x, y) {
        // true values first
        return (x === y)? 0 : x? -1 : 1;
        // false values first
        // return (x === y)? 0 : x? 1 : -1;
    });
    
    console.log(a);

Vous devez retourner 0 lorsque a et b ont tous deux la même valeur, -1 si a est vrai et 1 sinon.

131
c.P.u1

une manière plus simple:

a = [{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false}];

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

console.log(a);

vous pouvez appeler a.reverse () après le sort () si vous voulez qu'il soit trié dans l'autre sens.

EDIT: édité pour refléter la question mise à jour de trier un tableau d'objets au lieu d'un tableau de booléens.

27
dandavis

Solution simple:

[true, false, true, false].sort( (a,b) => b - a)

Pour empêcher la conversion de type implicite (que les langages comme TypeScript n'aiment pas), vous pouvez utiliser Number() pour convertir explicitement le booléen en nombre:

a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false];
a.sort(function(x, y) {
   return Number(x) - Number(y);
});
console.log(a);

Ou en utilisant les fonctions fléchées:

a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false];
a.sort((x, y) => Number(x) - Number(y));
console.log(a);
5
sroes

PFB, la solution a fonctionné pour moi dans TypeScript Angular 2 également,

  let a = [{aa:"1",xx:true},{aa:"10",xx:false},{aa:"2",xx:true},{aa:"11",xx:false},{aa:"3",xx:true},{aa:"12",xx:false},{aa:"4",xx:true},{aa:"13",xx:false},{aa:"5",xx:true},{aa:"14",xx:false},{aa:"6",xx:true},{aa:"15",xx:false},{aa:"7",xx:true},{aa:"16",xx:false},{aa:"8",xx:true},{aa:"17",xx:false},{aa:"9",xx:true},{aa:"18",xx:false}];

    //a.sort(function(a,b){return a.xx-b.xx});
    a.sort(function (x, y) {
        // true values first
        return (x.xx === y.xx) ? 0 : x ? -1 : 1;
        // false values first
        // return (x === y)? 0 : x? 1 : -1;
    });
    return JSON.stringify(a);
1
dreamdeveloper

Un tableau n'a pas de positions égales, alors pourquoi ne pas laisser le contrôle égal et renvoyer toujours -1 ou 1. Cette approche fonctionne bien avec TS.

a.sort(x => x ? -1 : 1)

Remarque: je suis un peu inquiet de la façon dont cela affecte les composants internes de la fonction de tri, mais cela semble faire l'affaire.

Si vous souhaitez inverser le tri

a.sort(x => !x ? -1 : 1)
1
CapK

Une solution assez simple pour la fonction de comparaison consiste à vérifier si a < b, cela donne 0 ou 1 lorsqu'il est converti en nombre. Nous voulons ensuite mapper 0 à -1 et 1 à 1. Pour ce faire, vous pouvez simplement multiplier par 2 puis soustraire 1.

data.sort(function (a, b) {
  return (a < b) * 2 - 1
}

ou juste

data.sort((a, b) => (a < b) * 2 - 1)

Problème trié!

Si l'une de vos valeurs est null elles sont traitées comme fausses (null*2 === 0) et toute valeur qui est undefined deviendra NaN (undefined*2 === NaN) ce qui devrait le faire durer dans les deux sens.

0
MattClimbs