Ordenar la propiedad del objeto por valores

696

Si tengo un objeto JavaScript como:

var list = {
  "you": 100, 
  "me": 75, 
  "foo": 116, 
  "bar": 15
};

¿Hay alguna forma de ordenar las propiedades en función del valor? Para que termine con

list = {
  "bar": 15, 
  "me": 75, 
  "you": 100, 
  "foo": 116
};
Steerpike
fuente
44
No solo "ordenar", sino más importante, ordenar números. Los números son inmunes al método Javascripts Array.sort (), lo que significa que no solo tendrá que encontrar un método para ordenar las propiedades, sino que tendrá que escribir su propia función para comparar los valores numéricos.
Sampson el
106
Antes de leer las respuestas: la respuesta es no . El orden de las propiedades del objeto no es estándar en ECMAScript. Nunca debe hacer suposiciones sobre el orden de los elementos en un objeto JavaScript. Un objeto es una colección desordenada de propiedades. Las respuestas a continuación le muestran cómo "usar" propiedades ordenadas, utilizando la ayuda de matrices, pero en realidad nunca alteran el orden de las propiedades de los propios objetos. Entonces, no, no es posible. Incluso si crea un objeto con propiedades preseleccionadas, no se garantiza que se muestren en el mismo orden en el futuro. Sigue leyendo :).
Govind Rai
3
@GovindRai todavía, en las aplicaciones frontend del mundo real, recorremos las colecciones de objetos con ID como claves y el orden es importante si se traduce a plantillas HTML. Dices que no tienen orden, yo digo que tienen exactamente el orden que veo cuando la consola los registra en el navegador actual. Y ese orden puede reordenarse. Tan pronto como los recorras, tienen una orden.
ProblemsOfSumit
77
@GovindRai: ahora hay un medio para acceder a las propiedades en un orden especificado en la especificación. ¿Es una buena idea? Casi seguro que no. :-) Pero está ahí, a partir de ES2015.
TJ Crowder
77
Visitantes de 2019: verifique esta Object.entriesrespuesta basada en apenas votos que es el estado de la técnica más limpio y legible desde ES2017: stackoverflow.com/a/37607084/245966
jakub.g

Respuestas:

705

Muévalos a una matriz, ordene esa matriz y luego use esa matriz para sus propósitos. Aquí hay una solución:

var maxSpeed = {
    car: 300, 
    bike: 60, 
    motorbike: 200, 
    airplane: 1000,
    helicopter: 400, 
    rocket: 8 * 60 * 60
};
var sortable = [];
for (var vehicle in maxSpeed) {
    sortable.push([vehicle, maxSpeed[vehicle]]);
}

sortable.sort(function(a, b) {
    return a[1] - b[1];
});

//[["bike", 60], ["motorbike", 200], ["car", 300],
//["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]

Una vez que tenga la matriz, puede reconstruir el objeto de la matriz en el orden que desee, logrando así exactamente lo que se propuso hacer. Eso funcionaría en todos los navegadores que conozco, pero dependería de una peculiaridad de implementación y podría romperse en cualquier momento. Nunca debe hacer suposiciones sobre el orden de los elementos en un objeto JavaScript.

var objSorted = {}
sortable.forEach(function(item){
    objSorted[item[0]]=item[1]
})
Nosredna
fuente
24
¿Puede reformular "puede reconstruir" a "puede usar una matriz para mantener el orden de las claves y extraer valores del objeto"? No solo no es estándar, como usted mismo ha mencionado, esta suposición errónea está rota por más navegadores que Chrome en la actualidad, por lo que es mejor no alentar a los usuarios a probarlo.
Oleg V. Volkov
32
Aquí hay una versión más compacta de su código. Object.keys (maxSpeed) .sort (function (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain
66
@TheBrain: Solo para agregar, keys()solo es compatible con IE9 + (y otros navegadores modernos), si eso es preocupante. También keys()excluye las propiedades enumerables de la cadena de prototipos de elementos (a diferencia de for..in), pero eso suele ser más deseable.
MrWhite
31
_.pairsconvierte un objeto en [[clave1, valor1], [clave2, valor2]]. Entonces llame a ordenar por eso. Luego invoque _.objectpara devolverlo.
Funkodebat
2
Mi proyecto requiere claves de objeto para fusionarse limpiamente, pero también requiere una ordenación explícita ya que los metadatos controlan la interfaz de usuario. Seguí un enfoque similar, solo que agregué una verificación hasOwnProperty para evitar rastrear la cadena de prototipos. Aquí hay un buen artículo sobre iterar sobre propiedades de objetos en JS hackernoon.com/…
Nathan Agersea
416

No queremos duplicar toda la estructura de datos, o usar una matriz donde necesitamos una matriz asociativa.

Aquí hay otra forma de hacer lo mismo que bonna:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted);     // bar,me,you,foo

Markus R
fuente
22
Esto parece estar ordenado por clave, no por valor, que no es lo que la pregunta requería.
Michael
27
Está ordenado por valor y muestra claves, pero perdemos el recuento de valores cuando se imprime, ya que solo imprime claves.
Hanna
66
El orden de las propiedades de los objetos no está garantizado en JavaScript, por lo que la ordenación debe realizarse en una matriz, no en un objeto (que es a lo que se refiere como una "matriz asociativa").
Christopher Meyers
66
No lo olvides keysSortedes una matriz! No es un objeto!
Verde
17
Si agrega .map(key => list[key]);al final de la clasificación, devolverá todo el objeto en lugar de solo la clave
James Moran,
183

Sus objetos pueden tener cualquier cantidad de propiedades y puede elegir ordenar por cualquier propiedad de objeto que desee, número o cadena, si coloca los objetos en una matriz. Considere esta matriz:

var arrayOfObjects = [   
    {
        name: 'Diana',
        born: 1373925600000, // Mon, Jul 15 2013
        num: 4,
        sex: 'female'
    },
    {

        name: 'Beyonce',
        born: 1366832953000, // Wed, Apr 24 2013
        num: 2,
        sex: 'female'
    },
    {            
        name: 'Albert',
        born: 1370288700000, // Mon, Jun 3 2013
        num: 3,
        sex: 'male'
    },    
    {
        name: 'Doris',
        born: 1354412087000, // Sat, Dec 1 2012
        num: 1,
        sex: 'female'
    }
];

ordenar por fecha de nacimiento, mayor primero

// use slice() to copy the array and not just make a reference
var byDate = arrayOfObjects.slice(0);
byDate.sort(function(a,b) {
    return a.born - b.born;
});
console.log('by date:');
console.log(byDate);

ordenar por nombre

var byName = arrayOfObjects.slice(0);
byName.sort(function(a,b) {
    var x = a.name.toLowerCase();
    var y = b.name.toLowerCase();
    return x < y ? -1 : x > y ? 1 : 0;
});

console.log('by name:');
console.log(byName);

http://jsfiddle.net/xsM5s/16/

inorganik
fuente
1
Ordenar por nombre no debe substrsalir del primer carácter; más Dianay Debratener un orden indefinido. Además, su byDatetipo realmente usa num, no born.
Lawrence Dol
Esto se ve bien, pero tenga en cuenta que para comparar cadenas solo puede usarx.localeCompare(y)
Jemar Jones
2
¡@JemarJones localCompareparece una función muy útil! Solo tenga en cuenta que no será compatible con todos los navegadores: IE 10 y menos, Safari Mobile 9 y menos.
inorganik
@inorganik Sí, muy buena nota para aquellos que necesitan apoyar esos navegadores
Jemar Jones
1
Este es un conjunto de Objetos, que no es el OP solicitado (un Objeto con varias propiedades)
João Pimentel Ferreira
62

Para completar, esta función devuelve una matriz ordenada de propiedades de objeto:

function sortObject(obj) {
    var arr = [];
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            arr.push({
                'key': prop,
                'value': obj[prop]
            });
        }
    }
    arr.sort(function(a, b) { return a.value - b.value; });
    //arr.sort(function(a, b) { a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); //use this to sort as strings
    return arr; // returns array
}

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var arr = sortObject(list);
console.log(arr); // [{key:"bar", value:15}, {key:"me", value:75}, {key:"you", value:100}, {key:"foo", value:116}]

Jsfiddle con el código anterior está aquí . Esta solución se basa en este artículo. .

El violín actualizado para ordenar cadenas está aquí. Puede eliminar ambas conversiones .toLowerCase () adicionales para la comparación de cadenas entre mayúsculas y minúsculas.

Stano
fuente
1
¿Qué pasa con una matriz de objetos? [{name: Will}, {name: Bill}, {name: Ben}]
Will Hancock el
1
Hola Will, puedes usar la función localeCompare para esta comparación. Lo agregó a la respuesta anterior.
Stano
Gran solución El tipo de cadena necesita un retorno
pfwd
@Stano Solución correcta y simple. Muchas gracias.
Abrar Hossain
48

Presenta ECMAScript 2017 Object.values / Object.entries. Como su nombre lo indica, el primero agrega todos los valores de un objeto en una matriz, y el segundo hace todo el objeto en una matriz de [key, value]matrices; El equivalente de Python dict.values()ydict.items() .

Las características hacen que sea bastante más fácil clasificar cualquier hash en un objeto ordenado. A partir de ahora, solo una pequeña parte de las plataformas JavaScript los admite , pero puede probarlo en Firefox 47+.

let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};

let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]

let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
kiding
fuente
¿Cómo responde esto posiblemente al título de la pregunta Sorting JavaScript Object by property value? Creo que entendió mal la pregunta, ya que debe cambiar el Objeto original y no crear una nueva Matriz a partir de él.
vsync
2
@vsync Esta respuesta da el mismo resultado que la respuesta aceptada, pero con menos código y sin variable temporal.
Darren Cook, el
3
FWIW, esta respuesta es clara y es la única que me ayudó.
NetOperator Wibby
solo en ff, no es decir, ni en cromo, clasifican los objetos automáticamente. wtf
fb
Solo tenga en cuenta que esto no conservará las claves.
Vael Victus
40

Un "flechas" versión de @marcusR 's respuesta de remisión

var myObj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(myObj).sort((a,b) => myObj[a]-myObj[b])
alert(keysSorted);     // bar,me,you,foo

ACTUALIZACIÓN: abril de 2017 : devuelve un myObjobjeto ordenado definido anteriormente.

Object
 .keys(myObj)
 .sort((a, b) => myObj[a]-myObj[b])
 .reduce((_sortedObj, key) => ({
   ..._sortedObj, 
   [key]: myObj[key]
 }), {})

Pruébalo aquí!

ACTUALIZACIÓN: octubre de 2018 - versión Object.entries

Object
 .entries(myObj)
 .sort()
 .reduce((_sortedObj, [k,v]) => ({
   ..._sortedObj, 
   [k]: v
 }), {})

Pruébalo aquí!

Jason J. Nathan
fuente
1
no funciona paravar myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
Rohanil
55
La pregunta del OP, junto con esta respuesta, no contiene objetos anidados @Rohanil Tal vez desee hacer otra pregunta en lugar de votar hacia abajo. Su objeto anidado con varios tipos obviamente necesita más de lo que proporciona esta solución
Jason J. Nathan
Solo una nota: sus actualizaciones no funcionarán en realidad. Al menos no en todas partes y no por eso entries. Según el estándar, un objeto es una colección desordenada de propiedades . Bueno, eso significa que si está tratando de construir el nuevo objeto después de ordenarlo por el valor de la propiedad o cualquier otra cosa, el orden de las claves de propiedad vuelve a estar indefinido. Chrome, por ejemplo, ordena de forma predeterminada las claves de propiedad, por lo que cada intento de ordenarlas de manera diferente es inútil. Su única posibilidad es obtener un "índice" basado en sus preferencias de pedido y recorrer el objeto original en consecuencia.
ZorgoZ
Sí @ZorgoZ, tienes razón y muchas personas lo han mencionado en esta publicación. La mayoría de las veces, usamos esta función como una transformación antes de convertir a otro tipo (como JSON) o antes de otra función de reducción. Si el objetivo es mutar el objeto a partir de entonces, puede haber resultados inesperados. He tenido éxito con esta función en todos los motores.
Jason J. Nathan
Nota: no desea usar sort()enObject.entries()
Solvitieg
36

Los objetos JavaScript están desordenados por definición (consulte la Especificación del lenguaje ECMAScript , sección 8.6). La especificación del lenguaje ni siquiera garantiza que, si itera sobre las propiedades de un objeto dos veces seguidas, saldrán en el mismo orden la segunda vez.

Si necesita ordenar cosas, use una matriz y el método Array.prototype.sort.

NickFitz
fuente
44
Tenga en cuenta que ha habido bastante discusión sobre esto. La mayoría de las implementaciones mantienen la lista en el orden en que se agregaron los elementos. IIRC, Chrome no. Hubo una discusión sobre si Chrome debería alinearse con las otras implementaciones. Creo que un objeto JavaScript es un hash y no se debe suponer ningún orden. Creo que Python pasó por el mismo argumento y recientemente se introdujo una nueva lista ordenada de tipo hash. Para la mayoría de los navegadores, PUEDES hacer lo que quieras recreando tu objeto, agregando elementos por valor ordenado. Pero no deberías.
Nosredna 01 de
Editar. Chrome generalmente mantiene el orden, pero no siempre. Y aquí está el error de Chromium relevante: code.google.com/p/chromium/issues/detail?id=883
Nosredna
66
Ese informe de error no está justificado, y los que confiaron en el comportamiento indocumentado son los que tienen los errores. Lea la sección 8.6 de ECMASCript; establece claramente que "Un objeto es una colección desordenada de propiedades". Cualquiera que descubriera que no parecía así en algunas implementaciones, y luego comenzó a depender de ese comportamiento específico de la implementación, cometió un gran error, y no deberían tratar de quitar la culpa de sí mismos. Si estuviera en el equipo de Chrome, marcaría ese informe de error como "Inválido, WontFix".
NickFitz 01 de
8
EcmaScript 5 en realidad define el orden de enumeración como el orden de inserción: la ausencia de definición se considera un error de especificación en ES3. Vale la pena señalar que la especificación EcmaScript define un comportamiento que nadie consideraría sensato; por ejemplo, el comportamiento de la especificación es que los errores de sintaxis en muchos casos se arrojan en tiempo de ejecución, el uso incorrecto de continuar, romper, ++, -, const, etc. según la especificación, cualquier motor que arroje una excepción antes de llegar a ese código es incorrecto
olliej
44
@olliej: no creo que esto sea correcto. La especificación dice: "No se especifica la mecánica y el orden de enumerar las propiedades (paso 6.a en el primer algoritmo, paso 7.a en el segundo)". Esto está en la página 92 ​​del PDF del borrador final.
whitneyland
25

OK , como ya sabrán, javascript tiene la función sort () , para ordenar las matrices, pero nada para el objeto ...

Entonces, en ese caso, necesitamos obtener de alguna manera la matriz de las claves y ordenarlas, esa es la razón por la que la API te da objetos en una matriz la mayor parte del tiempo, porque Array tiene más funciones nativas para jugar con ellas que el objeto literal, de todos modos, la solución rápida está usando Object.key que devuelve una matriz de las teclas de objeto, creo la función ES6 a continuación que hace el trabajo por usted, utiliza las funciones nativas sort () y reduce () en javascript:

function sortObject(obj) {
  return Object.keys(obj)
    .sort().reduce((a, v) => {
    a[v] = obj[v];
    return a; }, {});
}

Y ahora puedes usarlo así:

let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);

Verifique sortedMyObject y podrá ver el resultado ordenado por claves como esta:

{a: 1, b: 2, c: 3, d: 4, e: 5}

También de esta manera, el objeto principal no se tocará y en realidad obtendremos un nuevo objeto.

También creo la imagen a continuación, para que los pasos de la función sean más claros, en caso de que necesite cambiarlo un poco para que funcione a su manera:

Ordenar un objeto javascript por valor de propiedad

Alireza
fuente
44
Este orden por clave, no por valor.
ROROROOROROR
@ROROROOROROR, es solo una indicación de cómo funciona, ya que no son tan diferentes, pero todo bien, también agregaré la clasificación por valor
Alireza
1
Ordenar por valor es incorrecto y es su conjunto de datos. Cambia c: 3a c: 13y lo verás desmoronarse.
VtoCorleone
1
@VtoCorleone Eso es solo un error de clasificación natural, el primero es lo primero, no una falla en el algoritmo tal como se presenta.
Michael Ryan Soileau el
10
var list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
};

function sortAssocObject(list) {
    var sortable = [];
    for (var key in list) {
        sortable.push([key, list[key]]);
    }
    // [["you",100],["me",75],["foo",116],["bar",15]]

    sortable.sort(function(a, b) {
        return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
    });
    // [["bar",15],["me",75],["you",100],["foo",116]]

    var orderedList = {};
    for (var idx in sortable) {
        orderedList[sortable[idx][0]] = sortable[idx][1];
    }

    return orderedList;
}

sortAssocObject(list);

// {bar: 15, me: 75, you: 100, foo: 116}
Vasil Nikolov
fuente
Simple y perfecto! Esto responde a la pregunta. Gracias.
Ajay Singh
El orden de las claves no está garantizado en JavaScript, por lo que esto falla si las claves son números enteros o similares
ParoX
exacto, ParoX. Esto no funciona correctamente cuando la clave es de tipo entero.
jungwon jin
8

Actualización con ES6: si su preocupación es tener un objeto ordenado para recorrer en iteración (es por eso que me imagino que desea ordenar sus propiedades de objeto), puede usar el objeto Mapa .

Puede insertar sus pares (clave, valor) en orden ordenado y luego hacer un for..ofciclo garantizará que se repitan en el orden en que los insertó

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// 0 = zero 
// 1 = one
julianljk
fuente
También en ES6 (ES2015): Propiedades de los objetos no tienen fin (o si hay un medio de acceder a ellos en un orden definido, dependiendo de su punto de vista). Si los nombres de propiedad son cadenas y no parecen índices de matriz, el orden es el orden en que se agregaron al objeto. Esta orden se no especifica a ser respetado por for-ino Object.keys, sino que se define a ser respetado por Object.getOwnPropertyNamesy los otros nuevos métodos para acceder a las matrices nombre de la propiedad. Entonces esa es otra opción.
TJ Crowder
¿Pero dónde está la operación 'sort'? No están ordenados en absoluto
verde
@Green Creo que lo que quería resaltar aquí es que, en Maprealidad, tiene una estructura de datos que puede almacenar en orden ordenado (ordenar sus datos, recorrerlos y almacenarlos en el mapa) donde no está garantizado que con objetos.
julianljk
6

Underscore.js o Lodash.js para arreglos avanzados u tipos de objetos

 var data={
        "models": {

            "LTI": [
                "TX"
            ],
            "Carado": [
                "A",
                "T",
                "A(пасс)",
                "A(груз)",
                "T(пасс)",
                "T(груз)",
                "A",
                "T"
            ],
            "SPARK": [
                "SP110C 2",
                "sp150r 18"
            ],
            "Autobianchi": [
                "A112"
            ]
        }
    };

    var arr=[],
        obj={};
    for(var i in data.models){
      arr.push([i, _.sortBy(data.models[i],function (el){return el;})]);
    }
    arr=_.sortBy(arr,function (el){
      return el[0];
    });
    _.map(arr,function (el){return obj[el[0]]=el[1];});
     console.log(obj);

manifestación

Roman Yudin
fuente
6

Muy corto y simple!

var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
    sortedList[key] = list[key]; });
Maryam Koulaei
fuente
5

Estoy siguiendo la solución dada por slebetman (ve a leerla para todos los detalles), pero ajustada, ya que tu objeto no está anidado.

// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
    sort_array.push({key:key,value:list[key]});
}

// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});

// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
    var item = list[sort_array[i].key];

    // now do stuff with each item
}
bonna
fuente
4

Ordenar valores sin múltiples for-loops (para ordenar por las claves, cambie el índice en la devolución de llamada de clasificación a "0")

const list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
  };

let sorted = Object.fromEntries(
                Object.entries(list).sort( (a,b) => a[1] - b[1] )    
             ) 
console.log('Sorted object: ', sorted) 

dino4udo
fuente
2

Esta podría ser una manera simple de manejarlo como un objeto ordenado real. No estoy seguro de lo lento que es. También podría ser mejor con un bucle while.

Object.sortByKeys = function(myObj){
  var keys = Object.keys(myObj)
  keys.sort()
  var sortedObject = Object()
  for(i in keys){
    key = keys[i]
    sortedObject[key]=myObj[key]
   }

  return sortedObject

}

Y luego encontré esta función invertida en: http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/

Object.invert = function (obj) {

  var new_obj = {};

  for (var prop in obj) {
    if(obj.hasOwnProperty(prop)) {
      new_obj[obj[prop]] = prop;
    }
  }

  return new_obj;
};

Entonces

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
Carson Wright
fuente
2
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
  .sort((c,b) => {
    return a[b]-a[c]
  })
  .reduce((acc, cur) => {
    let o = {}
    o[cur] = a[cur]
    acc.push(o)
    return acc
   } , [])

salida = [{p: 8}, {c: 2}, {b: 1}, {g: 1}]

Kiran Debnath
fuente
2

Por si acaso, alguien está buscando mantener el objeto (con claves y valores), utilizando el código de referencia de @Markus R y el comentario de @James Moran, solo use:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
                 .map(key => newO[key] = list[key]);
console.log(newO);  // {bar: 15, me: 75, you: 100, foo: 116}
esneyderp
fuente
2
Estás devolviendo una tarea en eso map, forEachsería mejor
DiegoRBaquero
2
let toSort = {a:2323, b: 14, c: 799} 
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1]) 

Salida:

[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]
Remi Prasanna
fuente
1

muchas funciones similares y útiles: https://github.com/shimondoodkin/groupbyfunctions/

function sortobj(obj)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}

function sortobjkey(obj,key)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        k=key;      if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}
Shimon Doodkin
fuente
1

Objeto ordenado por valor (DESC)

function sortObject(list) {
  var sortable = [];
  for (var key in list) {
    sortable.push([key, list[key]]);
  }

  sortable.sort(function(a, b) {
    return (a[1] > b[1] ? -1 : (a[1] < b[1] ? 1 : 0));
  });

  var orderedList = {};
  for (var i = 0; i < sortable.length; i++) {
    orderedList[sortable[i][0]] = sortable[i][1];
  }

  return orderedList;
}
victorhazbun
fuente
1

Aquí hay un ejemplo más:

function sortObject(obj) {
  var arr = [];
  var prop;
  for (prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      arr.push({
        'key': prop,
        'value': obj[prop]
      });
    }
  }
  arr.sort(function(a, b) {
    return a.value - b.value;
  });
  return arr; // returns array
}
var list = {
  car: 300,
  bike: 60,
  motorbike: 200,
  airplane: 1000,
  helicopter: 400,
  rocket: 8 * 60 * 60
};
var arr = sortObject(list);
console.log(arr);

Mahendra Kulkarni
fuente
1
    var list = {
    "you": 100,
    "me": 75,
    "foo": 116,
    "bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
    var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
    tmpList[key] = list[key];
    delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
Milad Aslani
fuente
1

Mecanografiado

La siguiente función ordena el objeto por valor o una propiedad del valor. Si no usa TypeScript, puede eliminar la información de tipo para convertirla a JavaScript.

/**
 * Represents an associative array of a same type.
 */
interface Dictionary<T> {
  [key: string]: T;
}

/**
 * Sorts an object (dictionary) by value or property of value and returns
 * the sorted result as a Map object to preserve the sort order.
 */
function sort<TValue>(
  obj: Dictionary<TValue>,
  valSelector: (val: TValue) => number | string,
) {
  const sortedEntries = Object.entries(obj)
    .sort((a, b) =>
      valSelector(a[1]) > valSelector(b[1]) ? 1 :
      valSelector(a[1]) < valSelector(b[1]) ? -1 : 0);
  return new Map(sortedEntries);
}

Uso

var list = {
  "one": { height: 100, weight: 15 },
  "two": { height: 75, weight: 12 },
  "three": { height: 116, weight: 9 },
  "four": { height: 15, weight: 10 },
};

var sortedMap = sort(list, val => val.height);

El orden de las claves en un objeto JavaScript no está garantizado, por lo que estoy ordenando y devolviendo el resultado como un Mapobjeto que conserva el orden de clasificación.

Si desea convertirlo nuevamente a Objeto, puede hacer esto:

var sortedObj = {} as any;
sortedMap.forEach((v,k) => { sortedObj[k] = v });
orad
fuente
1

la entrada es objeto, la salida es objeto, usando lodash & js lib incorporado, con opción descendente o ascendente, y no muta el objeto de entrada

por ejemplo, entrada y salida

{
  "a": 1,
  "b": 4,
  "c": 0,
  "d": 2
}
{
  "b": 4,
  "d": 2,
  "a": 1,
  "c": 0
}

La implementación

const _ = require('lodash');

const o = { a: 1, b: 4, c: 0, d: 2 };


function sortByValue(object, descending = true) {
  const { max, min } = Math;
  const selector = descending ? max : min;

  const objects = [];
  const cloned = _.clone(object);

  while (!_.isEmpty(cloned)) {
    const selectedValue = selector(...Object.values(cloned));
    const [key, value] = Object.entries(cloned).find(([, value]) => value === selectedValue);

    objects.push({ [key]: value });
    delete cloned[key];
  }

  return _.merge(...objects);
}

const o2 = sortByValue(o);
console.log(JSON.stringify(o2, null, 2));
James T.
fuente
1
const arrayOfObjects = [
{name: 'test'},
{name: 'test2'}
]

const order = ['test2', 'test']

const setOrder = (arrayOfObjects, order) =>
    arrayOfObjects.sort((a, b) => {
        if (order.findIndex((i) => i === a.name) < order.findIndex((i) => i === b.name)) {
            return -1;
        }

        if (order.findIndex((i) => i === a.name) > order.findIndex((i) => i === b.name)) {
            return 1;
        }

        return 0;
    });
Oleg
fuente
1

mi solución con sort:

let list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
};

let sorted = Object.entries(list).sort((a,b) => a[1] - b[1]);

for(let element of sorted) {
    console.log(element[0]+ ": " + element[1]);
}
Ivan Bozveliev
fuente
Formatee su código como código
Itamar Mushkin
1
<pre>
function sortObjectByVal(obj){  
var keysSorted = Object.keys(obj).sort(function(a,b){return obj[b]-obj[a]});
var newObj = {};
for(var x of keysSorted){
    newObj[x] = obj[x];
}
return newObj;

}
var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
console.log(sortObjectByVal(list));
</pre>
Chirag Modi
fuente
1
Bienvenido a stackoverflow. Además de la respuesta que ha proporcionado, considere proporcionar una breve explicación de por qué y cómo soluciona el problema.
jtate
0

Otra forma de resolver esto: -

var res = [{"s1":5},{"s2":3},{"s3":8}].sort(function(obj1,obj2){ 
 var prop1;
 var prop2;
 for(prop in obj1) {
  prop1=prop;
 }
 for(prop in obj2) {
  prop2=prop;
 }
 //the above two for loops will iterate only once because we use it to find the key
 return obj1[prop1]-obj2[prop2];
});

// res tendrá la matriz de resultados

vivek_nk
fuente
0

Gracias y sigue respondiendo @Nosredna

Ahora que entendemos que el objeto debe convertirse en una matriz, luego ordene la matriz. Esto es útil para ordenar la matriz (o el objeto convertido en matriz) por cadena:

Object {6: Object, 7: Object, 8: Object, 9: Object, 10: Object, 11: Object, 12: Object}
   6: Object
   id: "6"
   name: "PhD"
   obe_service_type_id: "2"
   __proto__: Object
   7: Object
   id: "7"
   name: "BVC (BPTC)"
   obe_service_type_id: "2"
   __proto__: Object


    //Sort options
    var sortable = [];
    for (var vehicle in options)
    sortable.push([vehicle, options[vehicle]]);
    sortable.sort(function(a, b) {
        return a[1].name < b[1].name ? -1 : 1;
    });


    //sortable => prints  
[Array[2], Array[2], Array[2], Array[2], Array[2], Array[2], Array[2]]
    0: Array[2]
    0: "11"
    1: Object
        id: "11"
        name: "AS/A2"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2
        __proto__: Array[0]
    1: Array[2]
    0: "7"
    1: Object
        id: "7"
        name: "BVC (BPTC)"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2
Furia
fuente
0

Prueba esto. Incluso su objeto no tiene la propiedad en función de la cual está tratando de ordenar también se manejará.

Simplemente llámelo enviando propiedad con objeto.

var sortObjectByProperty = function(property,object){

    console.time("Sorting");
    var  sortedList      = [];
         emptyProperty   = [];
         tempObject      = [];
         nullProperty    = [];
    $.each(object,function(index,entry){
        if(entry.hasOwnProperty(property)){
            var propertyValue = entry[property];
            if(propertyValue!="" && propertyValue!=null){
              sortedList.push({key:propertyValue.toLowerCase().trim(),value:entry});  
            }else{
                emptyProperty.push(entry);
           }
        }else{
            nullProperty.push(entry);
        }
    });

      sortedList.sort(function(a,b){
           return a.key < b.key ? -1 : 1;
         //return a.key < b.key?-1:1;   // Asc 
         //return a.key < b.key?1:-1;  // Desc
      });


    $.each(sortedList,function(key,entry){
        tempObject[tempObject.length] = entry.value;
     });

    if(emptyProperty.length>0){
        tempObject.concat(emptyProperty);
    }
    if(nullProperty.length>0){
        tempObject.concat(nullProperty);
    }
    console.timeEnd("Sorting");
    return tempObject;
}
Vali Shah
fuente