reorder - Javascript ordena una matriz de objetos por una propiedad booleana
sort array of objects javascript (7)
Ver edición al final para el problema real.
Ok, tengo este escenario:
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]
Entonces si hago esto:
a.sort(function(a,b){return !a && b});
Me da esto:
[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]
Es algo así como hacer una especie ... pero no del todo ... :(
¿Cómo ordeno esta matriz?
EDITAR:
Si se está preguntando por qué no usé solo un.sort () es porque mi matriz real es de objetos, no una matriz simple como la que publiqué. El real tiene elementos que parecen [{xx: true}, {xx: false}, ...]
PFB la solución también funcionó para mí en Typescript Angular 2,
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);
Para evitar la conversión de tipo implícita (que no le gusta a los idiomas como TypeScript), puede usar Number()
para convertir explícitamente el booleano en un número:
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);
O usando las funciones de flecha:
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);
Solución simple:
[true, false, true, false].sort( (a,b) => b - a)
Una matriz no tiene posiciones iguales, así que ¿por qué no dejar de lado la verificación de iguales y devolver siempre -1 o 1. Este enfoque funciona bien con TS?
a.sort((x) => x ? -1 : 1)
Nota: Me preocupa un poco cómo afecta esto a los aspectos internos de la función de clasificación, pero parece que funciona.
Si quieres revertir ordenar
a.sort((x) => !x ? -1 : 1)
Una solución bastante simple para la función de comparación es verificar si a < b
, esto da 0 o 1 cuando se convierte a un número. Luego queremos mapear de 0 a -1 y de 1 a 1. Para hacerlo, simplemente multiplique por 2 y luego reste 1.
data.sort(function (a, b) {
return (a < b) * 2 - 1
}
o solo
data.sort((a, b) => (a < b) * 2 - 1)
Problema resuelto!
Si alguno de sus valores es null
, se tratará como falso ( null*2 === 0
) y cualquier valor que undefined
esté undefined
se convertirá en NaN
( undefined*2 === NaN
), lo que debería hacer que dure en cualquier dirección de clasificación.
una forma más sencilla:
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);
puede llamar a a.reverse () después de la ordenación () si desea que se ordene de otra manera ..
EDITAR: editado para reflejar la pregunta actualizada de ordenar una matriz de objetos en lugar de una matriz de valores booleanos.
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);
Debe devolver 0 cuando a y b tienen el mismo valor, -1 si a es verdadero y 1 en caso contrario.