Ordinamento della proprietà dell'oggetto per valori


696

Se ho un oggetto JavaScript come:

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

C'è un modo per ordinare le proprietà in base al valore? In modo che io finisca

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

4
Non solo "smistamento", ma soprattutto smistamento dei numeri. I numeri sono immuni al metodo Array.sort () di Javascripts, il che significa che non dovrai solo trovare un metodo per ordinare le proprietà, ma dovrai scrivere la tua funzione per confrontare i valori numerici.
Sampson,

106
Prima di leggere le risposte: La risposta è No . L'ordinamento delle proprietà dell'oggetto non è standard in ECMAScript. Non dovresti mai fare ipotesi sull'ordine degli elementi in un oggetto JavaScript. Un oggetto è una raccolta non ordinata di proprietà. Le risposte che seguono mostrano come "usare" le proprietà ordinate, usando l'aiuto di matrici, ma non modificare mai realmente l'ordine delle proprietà degli oggetti stessi. Quindi no, non è possibile. Anche se si crea un oggetto con proprietà preordinate, non è garantito che verranno visualizzate nello stesso ordine in futuro. Continuare a leggere :).
Govind Rai,

3
@GovindRai, tuttavia, nelle applicazioni di frontend del mondo reale passiamo in rassegna le raccolte di oggetti con ID come chiavi e l'ordine è importante se tradotto in modelli HTML. Dici che non hanno alcun ordine, io dico che hanno esattamente l'ordine che vedo quando li consulto nel blog corrente. E quell'ordine può essere riordinato. Non appena li attraversi, hanno un ordine.
ProblemsOfSumit

7
@GovindRai: ora esiste un modo per accedere alle proprietà in un ordine specificato nelle specifiche. È una buona idea? Quasi certamente no. :-) Ma è lì, a partire da ES2015.
TJ Crowder,

7
2019 visitatori: controllare questo malapena upvoted Object.entriesrisposta basata su che è lo stato più pulito e più leggibile dell'arte dal ES2017: stackoverflow.com/a/37607084/245966
jakub.g

Risposte:


705

Spostali in un array, ordina quell'array e quindi utilizza quell'array per i tuoi scopi. Ecco una soluzione:

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 volta che hai l'array, puoi ricostruire l'oggetto dall'array nell'ordine che preferisci, ottenendo così esattamente ciò che hai deciso di fare. Funzionerebbe in tutti i browser che conosco, ma dipenderà da una stranezza di implementazione e potrebbe interrompersi in qualsiasi momento. Non dovresti mai fare ipotesi sull'ordine degli elementi in un oggetto JavaScript.

var objSorted = {}
sortable.forEach(function(item){
    objSorted[item[0]]=item[1]
})

24
Puoi riformulare "puoi ricostruire" in "puoi usare l'array per mantenere l'ordine delle chiavi e estrarre i valori dall'oggetto"? Non solo non è standard, come hai già detto tu, questo presupposto errato è rotto da più browser rispetto a Chrome solo oggi, quindi è meglio non incoraggiare gli utenti a provarlo.
Oleg V. Volkov,

32
Ecco una versione più compatta del tuo codice. Object.keys (maxSpeed) .sort (function (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain,

6
@TheBrain: Giusto per aggiungere, keys()è supportato solo da IE9 + (e altri browser moderni), se questo è preoccupante. Inoltre keys()esclude le proprietà enumerabili dalla catena di prototipi degli elementi (diversamente da for..in), ma di solito è più desiderabile.
Mr White,

31
_.pairstrasforma un oggetto in [[chiave1, valore1], [chiave2, valore2]]. Quindi chiama l'ordinamento su quello. Quindi chiamalo _.objectper ripristinarlo.
Funkodebat,

2
Il mio progetto richiede chiavi dell'oggetto per l'unione in modo pulito, ma richiede anche l'ordinamento esplicito poiché i metadati guidano l'interfaccia utente. Ho seguito un approccio simile solo ho aggiunto un controllo hasOwnProperty per evitare di strisciare nella catena del prototipo. Ecco un buon articolo sull'iterazione delle
Nathan Agersea

416

Non vogliamo duplicare l'intera struttura dei dati o utilizzare un array in cui abbiamo bisogno di un array associativo.

Ecco un altro modo di fare la stessa cosa di 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


22
Questo sembra essere l'ordinamento per chiave, non per valore, che non è quello che chiedeva la domanda?
Michael,

27
È ordinato per valore e visualizza le chiavi, ma perdiamo il conteggio dei valori quando viene stampato, poiché stampa solo le chiavi.
Hanna,

6
L'ordine delle proprietà degli oggetti non è garantito in JavaScript, pertanto l'ordinamento deve essere eseguito in un array, non in un oggetto (che è ciò a cui ci si riferisce come "array associativo").
Christopher Meyers,

6
Non dimenticare. keysSortedè un array! Non un oggetto!
Verde

17
Se aggiungi .map(key => list[key]);alla fine dell'ordinamento, verrà restituito l'intero oggetto anziché solo la chiave
James Moran,

183

I tuoi oggetti possono avere qualsiasi quantità di proprietà e puoi scegliere di ordinare in base a qualsiasi proprietà dell'oggetto che desideri, numero o stringa, se metti gli oggetti in un array. Considera questo array:

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'
    }
];

ordina per data di nascita, prima il più vecchio

// 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);

ordina per nome

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/


1
L'ordinamento per nome non deve substrcontenere il primo carattere; altro Dianae Debrahanno un ordine indefinito. Inoltre, il tuo byDatetipo effettivamente utilizza num, non born.
Lawrence Dol

Questo sembra buono, ma nota che per confrontare le stringhe puoi semplicemente usarex.localeCompare(y)
Jemar Jones

2
@JemarJones localComparesembra una funzione molto utile! Tieni presente che non sarà supportato in tutti i browser: IE 10 e meno, Safari Mobile 9 e meno.
Inorganik,

@inorganik Sì, ottima nota per coloro che hanno bisogno di supportare quei browser
Jemar Jones,

1
Questa è una matrice di oggetti, che non è l'OP richiesto (un oggetto con diverse proprietà)
João Pimentel Ferreira,

62

Per completezza, questa funzione restituisce una matrice ordinata di proprietà dell'oggetto:

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 il codice sopra è qui . Questa soluzione si basa su questo articolo .

Il violino aggiornato per l'ordinamento delle stringhe è qui. Puoi rimuovere entrambe le conversioni aggiuntive .toLowerCase () da esso per il confronto di stringhe con distinzione tra maiuscole e minuscole.


1
Che dire di una serie di oggetti? [{name: Will}, {name: Bill}, {name: Ben}]
Will Hancock,

1
Ciao Will, puoi usare la funzione localeCompare per questo confronto. Aggiunto alla risposta sopra.
Stano,

Ottima soluzione L'ordinamento delle stringhe richiede un ritorno
pfwd

@Stano Soluzione corretta e semplice. Grazie mille.
Abrar Hossain,

48

ECMAScript 2017 introduce Object.values / Object.entries. Come suggerisce il nome, il primo aggrega tutti i valori di un oggetto in una matrice e il secondo fa l'intero oggetto in una matrice di [key, value]matrici; Python è l'equivalente di dict.values()e dict.items().

Le funzionalità semplificano l'ordinamento di qualsiasi hash in un oggetto ordinato. A partire da ora, solo una piccola parte delle piattaforme JavaScript li supporta , ma puoi provarlo su 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]]

come può forse rispondere al titolo della domanda Sorting JavaScript Object by property value? hai frainteso la domanda che penso, dal momento che devi cambiare l'oggetto originale e non creare una nuova matrice da esso.
vsync,

2
@vsync Questa risposta fornisce lo stesso risultato della risposta accettata, ma con meno codice e nessuna variabile temporanea.
Darren Cook,

3
FWIW, questa risposta è chiara ed è l'unica che mi ha aiutato.
NetOperator Wibby,

solo in ff, non cioè, né più in cromo ordinano gli oggetti automaticamente. wtf
fb,

Basta notare che questo non conserverà le chiavi.
Vael Victus l'

40

Una versione "dalla freccia" del @marcusR 's risposta per riferimento

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

AGGIORNAMENTO: aprile 2017 : restituisce un myObjoggetto ordinato sopra definito.

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

Provalo qui!

AGGIORNAMENTO: ottobre 2018 - Versione Object.entries

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

Provalo qui!


1
non funziona pervar myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
Rohanil,

5
La domanda del PO, insieme a questa risposta, non contiene oggetti nidificati @Rohanil Forse vorresti fare un'altra domanda invece di votare in negativo. Il tuo oggetto nidificato con vari tipi ha ovviamente bisogno di più di quanto questa soluzione fornisca
Jason J. Nathan il

Solo una nota: i tuoi aggiornamenti in realtà non funzioneranno. Almeno non ovunque e non a causa di entries. Secondo lo standard, un oggetto è una raccolta non ordinata di proprietà . Bene, ciò significa che se stai cercando di costruire il nuovo oggetto dopo averlo ordinato per valore di proprietà o qualsiasi altra cosa, l'ordinamento della chiave di proprietà diventa di nuovo indefinito. Chrome, ad esempio, ordina per impostazione predefinita le chiavi di proprietà, quindi ogni tentativo di ordinarle diversamente è inutile. La tua unica possibilità è quella di ottenere un "indice" basato sulle tue preferenze di ordine e attraversare l'oggetto originale di conseguenza.
ZorgoZ,

Sì @ZorgoZ, hai ragione e molte persone l'hanno menzionato in questo post. Il più delle volte, usiamo questa funzione come trasformazione prima di convertirla in un altro tipo (come JSON) o prima di un'altra funzione di riduzione. Se l'obiettivo è quello di mutare l'oggetto in seguito, potrebbero esserci risultati imprevisti. Ho avuto successo con questa funzione su tutti i motori.
Jason J. Nathan,

Nota: non si desidera utilizzare sort()suObject.entries()
Solvitieg

36

Gli oggetti JavaScript non sono ordinati per definizione (vedere la specifica del linguaggio ECMAScript , sezione 8.6). La specifica del linguaggio non garantisce nemmeno che, se si ripetono le proprietà di un oggetto due volte in successione, verranno fuori nello stesso ordine la seconda volta.

Se hai bisogno di cose da ordinare, usa un array e il metodo Array.prototype.sort.


4
Nota che c'è stato un bel po 'di discussioni su questo. La maggior parte delle implementazioni mantiene l'elenco nell'ordine in cui sono stati aggiunti gli elementi. IIRC, Chrome no. Ci sono state discussioni sul fatto che Chrome dovesse allinearsi con le altre implementazioni. La mia convinzione è che un oggetto JavaScript sia un hash e nessun ordine dovrebbe essere assunto. Credo che Python abbia affrontato lo stesso argomento e recentemente sia stata introdotta una nuova lista ordinata simile all'hash. Per la maggior parte dei browser, PUOI fare quello che vuoi ricreando il tuo oggetto, aggiungendo elementi per valore ordinato. Ma non dovresti.
Nosredna,

Modificare. Chrome di solito mantiene l'ordine, ma non sempre. Ed ecco il bug relativo di Chromium: code.google.com/p/chromium/issues/detail?id=883
Nosredna,

6
Quella segnalazione di bug è ingiustificata e coloro che si sono basati sul comportamento non documentato sono quelli con i bug. Leggi ECMASCript sezione 8.6; afferma chiaramente che "Un oggetto è una raccolta non ordinata di proprietà". Chiunque abbia scoperto che non sembrava così in alcune implementazioni, e poi ha iniziato a dipendere da quel comportamento specifico dell'implementazione, ha fatto un grosso errore e non dovrebbero cercare di spostare la colpa lontano da se stessi. Se fossi nel team di Chrome, contrassegnerei la segnalazione di bug come "Invalid, WontFix".
NickFitz,

8
EcmaScript 5 in realtà definisce l'ordine di enumerazione come l'ordine di inserimento - l'assenza di definizione è considerata un bug di specifica in ES3. Vale la pena notare che le specifiche EcmaScript definiscono un comportamento che nessuno considererebbe sano - ad esempio il comportamento delle specifiche è che in molti casi gli errori di sintassi vengono generati in fase di esecuzione, l'uso errato di continue, break, ++, -, const, ecc. secondo le specifiche, qualsiasi motore che genera un'eccezione prima di raggiungere quel codice è sbagliato
olliej

4
@olliej - Non penso sia corretto. La specifica dice: "La meccanica e l'ordine di enumerazione delle proprietà (passaggio 6.a nel primo algoritmo, passaggio 7.a nel secondo) non è specificato". Questo è a pagina 92 ​​del PDF della bozza finale.
Whitneyland,

25

OK , come forse saprai, JavaScript ha la funzione sort () , per ordinare le matrici, ma nulla per l'oggetto ...

Quindi, in quel caso, dobbiamo in qualche modo ottenere una matrice di chiavi e ordinarle, ecco il motivo per cui l'apis ti dà oggetti in una matrice per la maggior parte del tempo, perché la matrice ha più funzioni native per giocare con loro rispetto all'oggetto letterale, comunque, la rapida soluzione sta usando Object.key che restituisce un array di chiavi dell'oggetto, creo la funzione ES6 sotto la quale fa il lavoro per te, usa le funzioni native sort () e ridurre () in javascript:

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

E ora puoi usarlo in questo modo:

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

Controlla sortMyObject e puoi vedere il risultato ordinato per chiavi in ​​questo modo:

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

Anche in questo modo, l'oggetto principale non verrà toccato e stiamo effettivamente ottenendo un nuovo oggetto.

Creo anche l'immagine qui sotto, per rendere più chiari i passaggi della funzione, nel caso in cui sia necessario modificarlo un po 'per farlo a modo tuo:

Ordinamento di un oggetto javascript in base al valore della proprietà


4
Ordina per chiave, non per valore.
ROROROOROROR,

@ROROROOROROR, è solo un'indicazione di come funziona in quanto non sono così diversi, ma va bene, aggiungerò anche l'ordinamento per valore
Alireza,

1
L'ordinamento per valore è errato ed è il tuo set di dati. Passa c: 3a c: 13e lo vedrai cadere a pezzi.
VtoCorleone,

1
@VtoCorleone Questo è solo un errore di ordinamento naturale, 1 viene prima, non un difetto nell'algoritmo presentato.
Michael Ryan Soileau,

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}

Semplice e perfetto! Questo risponde alla domanda. Grazie.
Ajay Singh,

L'ordine delle chiavi non è garantito in javascript quindi questo non riesce per me se le chiavi sono numeri interi o simili
ParoX

esatto, ParoX. Questo non funziona correttamente quando la chiave è di tipo intero.
jungwon jin

8

Aggiornamento con ES6: se la tua preoccupazione è avere un oggetto ordinato da scorrere (motivo per cui immagino che tu voglia ordinare le proprietà del tuo oggetto), puoi usare l' oggetto Mappa .

Puoi inserire le tue coppie (chiave, valore) nell'ordine ordinato e quindi fare un for..ofciclo ti garantirà un ciclo nell'ordine in cui le hai inserite

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

Anche in ES6 (ES2015): proprietà degli oggetti non hanno ordine (o non v'è un mezzo di accedervi in un ordine definito, dipende dai punti di vista). Se i nomi delle proprietà sono stringhe e non sembrano indici di array, l'ordine è l'ordine in cui sono stati aggiunti all'oggetto. Questo ordine non è specificato per essere rispettato da for-ino Object.keys, ma è definito per essere rispettato da Object.getOwnPropertyNamese dagli altri nuovi metodi per accedere alle matrici di nomi di proprietà. Quindi questa è un'altra opzione.
TJ Crowder,

Ma dov'è l'operazione di "ordinamento"? Non sono affatto ordinati
Green

@Verde Penso che ciò che volevo evidenziare qui sia che, con Mapte, in realtà hai una struttura di dati che può archiviare in ordine ordinato (ordina i tuoi dati, esegui il ciclo e memorizzali nella mappa) dove non sei sicuro che con oggetti.
julianljk,

6

Underscore.js o Lodash.js per array avanzati o ordinamenti di oggetti

 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);

dimostrazione


6

Molto breve e semplice!

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

5

Sto seguendo la soluzione fornita da slebetman (vai a leggerlo per tutti i dettagli), ma modificato, poiché il tuo oggetto non è nidificato.

// 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
}

4

Ordinare i valori senza più for-loop (per ordinare in base alle chiavi, cambiare l'indice nel callback di ordinamento su "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) 


2

Questo potrebbe essere un modo semplice per gestirlo come un vero oggetto ordinato. Non sono sicuro di quanto sia lento. potrebbe anche essere migliore con un ciclo 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

}

E poi ho trovato questa funzione di inversione da: 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;
};

Così

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)

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
   } , [])

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


2

Nel caso in cui qualcuno stia cercando di mantenere l'oggetto (con chiavi e valori), usando il riferimento al codice di @Markus R e il commento di @James Moran, basta usare:

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}

2
Stai restituendo un incarico in questo map, forEachsarebbe meglio
DiegoRBaquero

2
let toSort = {a:2323, b: 14, c: 799} 
let sorted = Object.entries(toSort ).sort((a,b)=> a[1]-b[1]) 

Produzione:

[ [ "b", 14 ], [ "c", 799 ], [ "a", 2323 ] ]

1

molte funzioni simili e utili: 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;
}

1

Oggetto ordinato per valore (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;
}

1

Ecco un altro esempio:

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);


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 }

1

Dattiloscritto

La seguente funzione ordina l'oggetto per valore o una proprietà del valore. Se non usi TypeScript puoi rimuovere le informazioni sul tipo per convertirle in 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);

L'ordine delle chiavi in ​​un oggetto JavaScript non è garantito, quindi sto ordinando e restituendo il risultato come Mapoggetto che conserva l'ordinamento.

Se vuoi riconvertirlo in Object, puoi farlo:

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

1

l'input è oggetto, l'output è oggetto, usando la libreria incorporata lodash & js, con opzione decrescente o crescente, e non muta l'oggetto di input

ad es. input & output

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

L'implemento

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));

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;
    });

1

la mia soluzione con ordinamento:

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]);
}

Si prega di formattare il codice come codice
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>

1
Benvenuto in StackOverflow. Oltre alla risposta fornita, ti consigliamo di fornire una breve spiegazione del perché e di come risolvere il problema.
jtate

0

Un altro modo per risolvere questo: -

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 avrà l'array dei risultati


0

Grazie e continua a rispondere @Nosredna

Ora che comprendiamo che l'oggetto deve essere convertito in array, allora ordiniamo l'array. questo è utile per ordinare l'array (o l'oggetto convertito in array) per stringa:

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

0

Prova questo. Anche il tuo oggetto non ha la proprietà in base alla quale stai tentando di ordinare, inoltre verrà gestito.

Basta chiamarlo inviando proprietà con oggetto.

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.