objetos - ¿Cómo ordenar una matriz asociativa por sus valores en Javascript?
push javascript (9)
Aquí hay una variación de la respuesta de Ben Blank, si no te gustan las tuplas.
Esto te ahorra algunos personajes.
var keys = [];
for (var key in sortme) {
keys.push(key);
}
keys.sort(function(k0, k1) {
var a = sortme[k0];
var b = sortme[k1];
return a < b ? -1 : (a > b ? 1 : 0);
});
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
var value = sortme[key];
// Do something with key and value.
}
Tengo la matriz asociativa:
array["sub2"] = 1;
array["sub0"] = -1;
array["sub1"] = 0;
array["sub3"] = 1;
array["sub4"] = 0;
¿Cuál es la forma más elegante de ordenar (descender) por sus valores donde el resultado sería una matriz con los índices respectivos en este orden?
sub2, sub3, sub1, sub4, sub0?
Discusión continua y otras soluciones cubiertas en ¿Cómo ordenar una matriz (asociativa) por valor? con la mejor solución (para mi caso) siendo por saml (citado a continuación).
Las matrices solo pueden tener índices numéricos. Debería volver a escribir esto como un Objeto o como una Matriz de Objetos.
var status = new Array();
status.push({name: ''BOB'', val: 10});
status.push({name: ''TOM'', val: 3});
status.push({name: ''ROB'', val: 22});
status.push({name: ''JON'', val: 7});
Si te gusta el método status.push
, puedes ordenarlo con:
status.sort(function(a,b) {
return a.val - b.val;
});
En lugar de corregirte sobre la semántica de una "matriz asociativa", creo que esto es lo que quieres:
function getSortedKeys(obj) {
var keys = []; for(var key in obj) keys.push(key);
return keys.sort(function(a,b){return obj[b]-obj[a]});
}
Usted coloca un objeto (como el suyo) y obtiene una matriz de las propiedades - eh properties - atrás, ordenadas descendiendo por el valor (numérico) de los valores, eh, del objeto eh.
Esto solo funciona si tus valores son numéricos. Ajuste la pequeña function(a,b)
allí para cambiar el mecanismo de clasificación para que funcione de forma ascendente, o trabaje para valores de string
(por ejemplo). Izquierda como ejercicio para el lector.
EDITAR: la gente sigue votando esta respuesta, pero es muy vieja. Por favor reconsidera por qué no estás usando Object.keys() hoy en día.
Javascript no tiene "matrices asociativas" en la forma en que piensas en ellas. En cambio, simplemente tiene la capacidad de establecer propiedades de objetos usando una sintaxis similar a una matriz (como en su ejemplo), además de la capacidad de iterar sobre las propiedades de un objeto.
El resultado de esto es que no hay garantía en cuanto al orden en que se repiten las propiedades, por lo que no hay nada como un género para ellos. En su lugar, deberá convertir las propiedades de su objeto en una matriz "verdadera" (que garantiza el orden). Aquí hay un fragmento de código para convertir un objeto en una matriz de dos tuplas (matrices de dos elementos), ordenándolo como usted describe, y luego iterando sobre él:
var tuples = [];
for (var key in obj) tuples.push([key, obj[key]]);
tuples.sort(function(a, b) {
a = a[1];
b = b[1];
return a < b ? -1 : (a > b ? 1 : 0);
});
for (var i = 0; i < tuples.length; i++) {
var key = tuples[i][0];
var value = tuples[i][1];
// do something with key and value
}
Puede que le resulte más natural ajustar esto en una función que toma una devolución de llamada:
function bySortedValue(obj, callback, context) {
var tuples = [];
for (var key in obj) tuples.push([key, obj[key]]);
tuples.sort(function(a, b) {
return a[1] < b[1] ? 1 : a[1] > b[1] ? -1 : 0
});
var length = tuples.length;
while (length--) callback.call(context, tuples[length][0], tuples[length][1]);
}
bySortedValue({
foo: 1,
bar: 7,
baz: 3
}, function(key, value) {
document.getElementById(''res'').innerHTML += `${key}: ${value}<br>`
});
<p id=''res''>Result:<br/><br/><p>
La respuesta de @ commonpike es "la correcta", pero a medida que continúa comentando ...
la mayoría de los navegadores actuales solo son compatibles con
Object.keys()
Sí ... Object.keys()
es mucho mejor .
Pero lo que es aún mejor ? Duh, es en coffeescript
!
sortedKeys = (x) -> Object.keys(x).sort (a,b) -> x[a] - x[b]
sortedKeys
''a'' : 1
''b'' : 3
''c'' : 4
''d'' : -1
[ ''d'', ''a'', ''b'', ''c'' ]
No se requiere complicación innecesaria ...
function sortMapByValue(map)
{
var tupleArray = [];
for (var key in map) tupleArray.push([key, map[key]]);
tupleArray.sort(function (a, b) { return a[1] - b[1] });
return tupleArray;
}
Realmente no hay nada como una "matriz asociativa" en JavaScript. Lo que tienes allí es solo un viejo objeto simple. Por supuesto, funcionan como arreglos asociativos tipo kind-of, y las claves están disponibles, pero no hay semántica en el orden de las teclas.
Puede convertir su objeto en una matriz de objetos (pares clave / valor) y ordenarlo:
function sortObj(object, sortFunc) {
var rv = [];
for (var k in object) {
if (object.hasOwnProperty(k)) rv.push({key: k, value: object[k]});
}
rv.sort(function(o1, o2) {
return sortFunc(o1.key, o2.key);
});
return rv;
}
Entonces llamarías eso con una función de comparación.
Simplemente está ahí y alguien está buscando tuplas basadas en géneros. Esto comparará el primer elemento del objeto en la matriz, que el segundo elemento y así sucesivamente. es decir, en el ejemplo siguiente, primero se comparará con "a", luego con "b" y así sucesivamente.
let arr = [
{a:1, b:2, c:3},
{a:3, b:5, c:1},
{a:2, b:3, c:9},
{a:2, b:5, c:9},
{a:2, b:3, c:10}
]
function getSortedScore(obj) {
var keys = [];
for(var key in obj[0]) keys.push(key);
return obj.sort(function(a,b){
for (var i in keys) {
let k = keys[i];
if (a[k]-b[k] > 0) return -1;
else if (a[k]-b[k] < 0) return 1;
else continue;
};
});
}
console.log(getSortedScore(arr))
OUPUTS
[ { a: 3, b: 5, c: 1 },
{ a: 2, b: 5, c: 9 },
{ a: 2, b: 3, c: 10 },
{ a: 2, b: 3, c: 9 },
{ a: 1, b: 2, c: 3 } ]
Yo uso $ .each de jquery pero puedes hacerlo con un ciclo for, una mejora es esta:
//.ArraySort(array)
/* Sort an array
*/
ArraySort = function(array, sortFunc){
var tmp = [];
var aSorted=[];
var oSorted={};
for (var k in array) {
if (array.hasOwnProperty(k))
tmp.push({key: k, value: array[k]});
}
tmp.sort(function(o1, o2) {
return sortFunc(o1.value, o2.value);
});
if(Object.prototype.toString.call(array) === ''[object Array]''){
$.each(tmp, function(index, value){
aSorted.push(value.value);
});
return aSorted;
}
if(Object.prototype.toString.call(array) === ''[object Object]''){
$.each(tmp, function(index, value){
oSorted[value.key]=value.value;
});
return oSorted;
}
};
Entonces ahora puedes hacer
console.log("ArraySort");
var arr1 = [4,3,6,1,2,8,5,9,9];
var arr2 = {''a'':4, ''b'':3, ''c'':6, ''d'':1, ''e'':2, ''f'':8, ''g'':5, ''h'':9};
var arr3 = {a: ''green'', b: ''brown'', c: ''blue'', d: ''red''};
var result1 = ArraySort(arr1, function(a,b){return a-b});
var result2 = ArraySort(arr2, function(a,b){return a-b});
var result3 = ArraySort(arr3, function(a,b){return a>b});
console.log(result1);
console.log(result2);
console.log(result3);