Sortowanie właściwości obiektu według wartości


697

Jeśli mam obiekt JavaScript, taki jak:

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

Czy istnieje sposób sortowania właściwości według wartości? Tak więc skończę z

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

4
Nie tylko „sortowanie”, ale przede wszystkim sortowanie liczb. Liczby są odporne na metodę Javascript Array.sort (), co oznacza, że ​​nie tylko będziesz musiał znaleźć metodę sortowania właściwości, ale będziesz musiał napisać własną funkcję, aby porównać wartości liczbowe.
Sampson,

107
Zanim przeczytasz odpowiedzi: Odpowiedź brzmi: nie . Kolejność właściwości obiektów w ECMAScript jest niestandardowa. Nigdy nie należy przyjmować założeń dotyczących kolejności elementów w obiekcie JavaScript. Obiekt to nieuporządkowany zbiór właściwości. Poniższe odpowiedzi pokazują, jak „używać” posortowanych właściwości za pomocą tablic, ale nigdy tak naprawdę nie zmieniać kolejności właściwości samych obiektów. Więc nie, nie jest to możliwe. Nawet jeśli zbudujesz obiekt ze wstępnie ustawionymi właściwościami, nie ma gwarancji, że będą one wyświetlane w tej samej kolejności w przyszłości. Czytaj :).
Govind Rai

3
@GovindRai jeszcze, w rzeczywistych aplikacjach frontendowych przeglądamy kolekcje obiektów z identyfikatorami jako kluczami, a kolejność jest ważna, jeśli przetłumaczona na szablony HTML. Mówisz, że nie mają kolejności, mówię, że mają dokładnie taką kolejność, jaką widzę, gdy console.loguje je w bieżącej przeglądarce. I to zamówienie można zmienić. Gdy tylko je zapętlisz, mają rozkaz.
ProblemsOfSumit,

7
@GovindRai: Istnieje teraz sposób uzyskiwania dostępu do właściwości w określonej kolejności w specyfikacji. Czy to dobry pomysł? Prawie na pewno nie. :-) Ale jest tam, począwszy od ES2015.
TJ Crowder

7
Odwiedzający 2019: sprawdź tę ledwo ocenioną Object.entriesodpowiedź, która jest najczystszym i najbardziej czytelnym stanem wiedzy od ES2017: stackoverflow.com/a/37607084/245966
jakub.g

Odpowiedzi:


705

Przenieś je do tablicy, posortuj tę tablicę, a następnie użyj tej tablicy do swoich celów. Oto rozwiązanie:

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]]

Gdy już będziesz mieć tablicę, możesz odbudować obiekt z tablicy w wybranej przez siebie kolejności, osiągając dokładnie to, co masz zamiar zrobić. Działa to we wszystkich przeglądarkach, o których wiem, ale byłoby to zależne od dziwactwa implementacyjnego i może się zepsuć w dowolnym momencie. Nigdy nie należy przyjmować założeń dotyczących kolejności elementów w obiekcie JavaScript.

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

24
Czy możesz przeformułować „możesz odbudować” na „możesz użyć tablicy do utrzymania kolejności kluczy i wyciągania wartości z obiektu”? Nie tylko jest to niestandardowe, jak już wspomniałeś, to błędne założenie zostało złamane przez większą liczbę przeglądarek niż tylko dzisiaj Chrome, więc lepiej nie zachęcać użytkowników do wypróbowania go.
Oleg V. Volkov

32
Oto bardziej kompaktowa wersja twojego kodu. Object.keys (maxSpeed) .sort (funkcja (a, b) {return - (maxSpeed ​​[a] - maxSpeed ​​[b])});
TheBrain

6
@TheBrain: Wystarczy dodać, keys()jest obsługiwany tylko przez IE9 + (i inne nowoczesne przeglądarki), jeśli to dotyczy. keys()Wyklucza również wyliczalne właściwości z łańcucha prototypów elementów (w przeciwieństwie do for..in) - ale jest to zwykle bardziej pożądane.
MrWhite

31
_.pairszamienia obiekt w [[klucz1, wartość1], [klucz2, wartość2]]. Następnie wywołaj sort na ten temat. Następnie zadzwoń _.object, aby cofnąć.
Funkodebat

2
Mój projekt wymaga kluczy obiektowych do czystego scalenia, ale wymaga również jawnego sortowania, ponieważ metadane napędzają interfejs użytkownika. Zastosowałem podobne podejście, ale dodałem test hasOwnProperty, aby uniknąć przeszukiwania łańcucha prototypów. Oto dobry artykuł na temat iteracji właściwości obiektu w JS hackernoon.com/…
Nathan Agersea

416

Nie chcemy powielać całej struktury danych ani używać tablicy, w której potrzebujemy tablicy asocjacyjnej.

Oto inny sposób na zrobienie tego samego, co 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
Wydaje się, że jest to sortowanie według klucza, a nie wartości, a nie tego wymagało pytanie?
Michael

27
Jest sortowane według wartości i wyświetla klucze - ale tracimy licznik wartości podczas drukowania, ponieważ drukuje tylko klucze.
Hanna

6
W JavaScript nie jest gwarantowana kolejność właściwości obiektów, więc sortowanie powinno odbywać się w tablicy, a nie w obiekcie (co nazywamy „tablicą asocjacyjną”).
Christopher Meyers

6
Nie zapomnij keysSortedjest tablicą! Nie przedmiot!
Zielony

17
Jeśli dodasz .map(key => list[key]);na końcu tego rodzaju, zwróci cały obiekt zamiast tylko klucza
James Moran

184

Twoje obiekty mogą mieć dowolną liczbę właściwości i możesz sortować według dowolnej właściwości obiektu, liczby lub łańcucha, jeśli umieścisz obiekty w tablicy. Rozważ tę tablicę:

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

sortuj według daty urodzenia, najpierw najstarszej

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

sortuj według nazwy

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
Sortuj według nazwy nie powinna substrwyróżniać pierwszego znaku; jeszcze Dianai Debramieć niezdefiniowany porządek. Ponadto twój byDaterodzaj faktycznie używa num, a nie born.
Lawrence Dol

Wygląda to dobrze, ale pamiętaj, że aby porównać ciągi, których możesz po prostu użyćx.localeCompare(y)
Jemar Jones

2
@JemarJones localComparewygląda na bardzo przydatną funkcję! Pamiętaj, że nie będzie obsługiwany w każdej przeglądarce - IE 10 i mniej, Safari Mobile 9 i mniej.
inorganik

@inorganik Tak, bardzo dobra notatka dla tych, którzy muszą obsługiwać te przeglądarki
Jemar Jones

1
Jest to tablica Obiektów, o które nie poprosił OP (Obiekt o kilku właściwościach)
João Pimentel Ferreira

62

Dla zachowania kompletności ta funkcja zwraca posortowaną tablicę właściwości obiektu:

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 z powyższym kodem jest tutaj . To rozwiązanie jest oparte na tym artykule .

Zaktualizowany skrzypce do sortowania ciągów jest tutaj. Możesz usunąć zarówno dodatkowe konwersje .toLowerCase () w celu porównania ciągów znaków z rozróżnianiem wielkości liter.


1
Co z tablicą obiektów? [{name: Will}, {name: Bill}, {name: Ben}]
Will Hancock

1
Cześć Will, możesz użyć funkcji localeCompare do tego porównania. Dodano to do powyższej odpowiedzi.
Stano

Świetne rozwiązanie. Sortowanie ciągów wymaga zwrotu
pfwd

@Stano Prawidłowe i proste rozwiązanie. Dzięki wielkie.
Abrar Hossain

48

ECMAScript 2017 wprowadza Object.values / Object.entries. Jak sama nazwa wskazuje, pierwsza z nich agreguje wszystkie wartości obiektu w tablicę, a druga łączy cały obiekt w tablicę [key, value]tablic; Odpowiednik dict.values()idict.items() .

Funkcje ułatwiają sortowanie dowolnego skrótu w uporządkowanym obiekcie. Na razie obsługuje je tylko niewielka część platform JavaScript , ale możesz wypróbować ją w przeglądarce 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]]

jak to może odpowiedzieć na tytuł pytania Sorting JavaScript Object by property value? myślę, że źle zrozumiałeś pytanie, ponieważ musisz zmienić oryginalny Obiekt i nie tworzyć z niego nowej Tablicy.
vsync

2
@vsync Ta odpowiedź daje taki sam wynik jak odpowiedź zaakceptowana, ale z mniejszym kodem i bez zmiennej tymczasowej.
Darren Cook

3
FWIW, ta odpowiedź jest czysta i jest jedyną, która mi pomogła.
NetOperator Wibby,

tylko w ff, nie tj. ani chrom już nie sortują obiektów automatycznie. wtf
fb

Pamiętaj tylko, że nie zachowa to kluczy.
Vael Victus,

40

Określenie „strzałką” wersja @marcusR „s odpowiedź odsyłającego

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

AKTUALIZACJA: kwiecień 2017 r. - Zwraca posortowany myObjobiekt zdefiniowany powyżej.

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

Wypróbuj tutaj!

AKTUALIZACJA: październik 2018 r. - Wersja Object.entries

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

Wypróbuj tutaj!


1
nie działa dlavar myObj = {"1": {"Value": 40}, "2": {"Value": 10}, "3": {"Value": 30}, "4": {"Value": 20}};
Rohanil

5
Pytanie OP wraz z tą odpowiedzią nie zawiera zagnieżdżonych obiektów @Rohanil Może chciałbyś zadać inne pytanie zamiast głosowania w dół. Twój obiekt zagnieżdżony z różnymi typami oczywiście potrzebuje więcej niż zapewnia to rozwiązanie
Jason J. Nathan

Uwaga: twoje aktualizacje nie będą działać. Przynajmniej nie wszędzie i nie z powodu entries. Zgodnie ze standardem obiekt jest nieuporządkowanym zbiorem właściwości . Oznacza to, że jeśli próbujesz zbudować nowy obiekt po posortowaniu go według wartości właściwości lub czegokolwiek innego, kolejność kluczy właściwości staje się ponownie niezdefiniowana. Na przykład Chrome domyślnie porządkuje klucze właściwości, dlatego każda próba uporządkowania ich inaczej jest bezużyteczna. Jedyną szansą jest uzyskanie „indeksu” na podstawie preferencji dotyczących zamawiania i odpowiednie przejście do oryginalnego obiektu.
ZorgoZ,

Tak @ZorgoZ, masz rację i wiele osób wspomniało o tym w tym poście. Przez większość czasu używamy tej funkcji jako transformacji przed konwersją na inny typ (jak JSON) lub przed inną funkcją redukcji. Jeśli celem jest następnie zmutowanie obiektu, mogą wystąpić nieoczekiwane wyniki. Odniosłem sukces z tą funkcją we wszystkich silnikach.
Jason J. Nathan

Uwaga: nie chcesz używać sort()naObject.entries()
Solvitieg

36

Obiekty JavaScript są z definicji nieuporządkowane (patrz specyfikacja języka ECMAScript , rozdział 8.6). Specyfikacja języka nawet nie gwarantuje, że jeśli powtórzysz właściwości obiektu dwa razy pod rząd, pojawią się one w tej samej kolejności za drugim razem.

Jeśli potrzebujesz rzeczy do zamówienia, użyj tablicy i metody Array.prototype.sort.


4
Zauważ, że było o to sporo kłótni. Większość implementacji utrzymuje listę w kolejności, w której dodano elementy. IIRC, Chrome nie. Dyskutowano o tym, czy Chrome powinien być zgodny z innymi implementacjami. Wierzę, że obiekt JavaScript jest skrótem i nie należy przyjmować żadnej kolejności. Wierzę, że Python przeszedł przez ten sam argument i niedawno wprowadzono nową uporządkowaną listę przypominającą skrót. W większości przeglądarek MOŻESZ robić, co chcesz, odtwarzając obiekt, dodając elementy według posortowanej wartości. Ale nie powinieneś.
Nosredna

Edytować. Chrome zwykle utrzymuje porządek, ale nie zawsze. A oto odpowiedni błąd Chromium: code.google.com/p/chromium/issues/detail?id=883
Nosredna

6
Ten raport o błędzie jest nieuzasadniony, a ci, którzy polegali na nieudokumentowanym zachowaniu, mają błędy. Przeczytaj ECMASCript rozdział 8.6; wyraźnie stwierdza, że ​​„Obiekt jest nieuporządkowanym zbiorem właściwości”. Każdy, kto odkrył, że tak nie wyglądało w kilku implementacjach, a potem zaczął polegać na tym specyficznym dla implementacji zachowaniu, popełnił duży błąd i nie powinien starać się odrzucić winy od siebie. Gdybym był członkiem zespołu Chrome, oznaczyłbym ten raport o błędzie jako „Nieprawidłowy, WontFix”.
NickFitz

8
EcmaScript 5 faktycznie definiuje kolejność wyliczania jako kolejność wstawiania - brak definicji jest uważany za błąd specyfikacji w ES3. Warto zauważyć, że specyfikacja EcmaScript określa zachowanie, które nikt nie uznałby za rozsądne - na przykład zachowanie specyfikacji polega na tym, że błędy składniowe są w wielu przypadkach zgłaszane w czasie wykonywania, nieprawidłowe użycie kontynuacji, przerwania, ++, -, const itp. do specyfikacji każdy silnik, który zgłasza wyjątek przed osiągnięciem tego kodu, jest niepoprawny
olliej

4
@olliej - Nie sądzę, żeby to było poprawne. Specyfikacja mówi: „Mechanika i kolejność wyliczania właściwości (krok 6.a w pierwszym algorytmie, krok 7.a w drugim) nie jest określona”. To jest na stronie 92 PDF ostatecznego szkicu.
Whitneyland

25

OK , jak zapewne wiesz, javascript ma funkcję sort () do sortowania tablic, ale nic dla obiektu ...

W takim przypadku musimy jakoś pobrać tablicę kluczy i posortować je, dlatego api daje ci większość obiektów w tablicy, ponieważ tablica ma więcej rodzimych funkcji do zabawy z nimi niż dosłownie obiekt, szybkim rozwiązaniem jest użycie Object.key, które zwracają tablicę kluczy obiektowych, tworzę ES6 poniżej, która wykonuje za ciebie zadanie, używa natywnych funkcji sort () i redukuj () w javascript:

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

A teraz możesz użyć tego w następujący sposób:

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

Sprawdź sortedMyObject i możesz zobaczyć wynik posortowany według następujących kluczy:

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

Również w ten sposób główny obiekt nie zostanie dotknięty i faktycznie otrzymamy nowy obiekt.

Tworzę również poniższy obrazek, aby uczynić kroki funkcji bardziej wyraźnymi, na wypadek, gdyby trzeba było trochę je zmienić, aby działały po swojemu:

Sortowanie obiektu javascript według wartości właściwości


4
Sortuj według klucza, a nie według wartości.
ROROROOROROR

@ROROROOROROR, to tylko wskazówka, jak to działa, ponieważ nie są one tak różne, ale wszystko w porządku, dodam sortowanie według wartości
Alireza

1
Sortowanie według wartości jest nieprawidłowe i jest to Twój zestaw danych. Zmień c: 3na, c: 13a zobaczysz, jak się rozpada.
VtoCorleone,

1
@ VtoCorleone To tylko naturalny błąd sortowania, pierwszy jest pierwszy, a nie błąd w przedstawionym algorytmie.
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}

Prosty i idealny! To odpowiada na pytanie. Dzięki.
Ajay Singh

Kolejność kluczy nie jest gwarantowana w javascript, więc dla mnie nie powiedzie się, jeśli klucze są liczbami całkowitymi lub podobnymi
ParoX

dokładnie, ParoX. To nie działa poprawnie, gdy klucz jest liczbą całkowitą.
jungwon jin

8

Zaktualizuj za pomocą ES6: Jeśli twoja obawa dotyczy posortowanego obiektu do iteracji (dlatego wyobrażam sobie, że chcesz posortować właściwości obiektu), możesz użyć obiektu Map .

Możesz wstawić pary (klucz, wartość) w posortowanej kolejności, a następnie wykonanie for..ofpętli zagwarantuje, że będą one zapętlone w kolejności, w której je wstawiłeś

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

Również w ES6 (ES2015): Właściwości obiektu należy mieć porządek (lub nie jest środkiem dostępu do nich w określonej kolejności, w zależności od punktu widzenia). Jeśli nazwy właściwości są łańcuchami i nie wyglądają jak indeksy tablic, kolejność jest kolejnością, w jakiej zostały dodane do obiektu. Ta kolejność nie jest określana jako przestrzegana przez for-inlub Object.keys, ale jest zdefiniowana jako przestrzegana przez Object.getOwnPropertyNamesinne nowe metody dostępu do tablic nazw właściwości. To kolejna opcja.
TJ Crowder

Ale gdzie jest operacja „sortowania”? W ogóle nie są sortowane
Green

@Green Myślę, że chciałem tutaj podkreślić, Mapże w rzeczywistości masz strukturę danych, która może przechowywać w posortowanej kolejności (sortuj dane, przeglądaj je i przechowuj na mapie), ponieważ nie masz gwarancji, że dzięki przedmioty
julianljk

6

Underscore.js lub Lodash.js do zaawansowanego sortowania tablic lub obiektów

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

próbny


6

Bardzo krótki i prosty!

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

5

Postępuję zgodnie z rozwiązaniem podanym przez slebetman (przeczytaj wszystkie szczegóły), ale dostosowałem, ponieważ twój obiekt nie jest zagnieżdżony.

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

Sortuj wartości bez wielu pętli for (aby sortować według kluczy, zmień indeks w wywołaniu zwrotnym sortowania na „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

Może to być prosty sposób, aby potraktować go jako obiekt naprawdę uporządkowany. Nie jestem pewien, jak wolno. również może być lepiej z pętlą 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

}

A potem znalazłem tę funkcję inwersji z: 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;
};

Więc

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

Na wszelki wypadek ktoś szuka utrzymania obiektu (z kluczami i wartościami), korzystając z odwołania do kodu autorstwa @ Markus R i komentarza @James Moran, wystarczy użyć:

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
mapforEach
Zwrócisz

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

Wynik:

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

1

wiele podobnych i przydatnych funkcji: 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

Obiekt posortowany według wartości (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

Oto jeszcze jeden przykład:

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

Maszynopis

Poniższa funkcja sortuje obiekt według wartości lub właściwości wartości. Jeśli nie używasz TypeScript, możesz usunąć informacje o typie, aby przekonwertować je na 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);
}

Stosowanie

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

Kolejność kluczy w obiekcie JavaScript nie jest gwarantowana, więc sortuję i zwracam wynik jako Mapobiekt, który zachowuje porządek sortowania.

Jeśli chcesz przekonwertować go z powrotem na obiekt, możesz to zrobić:

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

1

dane wejściowe są obiektami, dane wyjściowe są obiektami, przy użyciu wbudowanej biblioteki libash & js, z opcją malejącą lub rosnącą i nie powoduje mutacji obiektu wejściowego

np. wejście i wyjście

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

Implementacja

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

moje rozwiązanie z sortowaniem:

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

Sformatuj kod jako kod
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
Witamy w Stackoverflow. Oprócz udzielonej odpowiedzi rozważ krótkie wyjaśnienie, dlaczego i jak to rozwiązuje problem.
jtate

0

Innym sposobem rozwiązania tego jest:

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 będzie miała tablicę wyników


0

Dziękuję i kontynuuj odpowiedź @Nosredna

Teraz, gdy rozumiemy, obiekt należy przekonwertować na tablicę, a następnie posortować tablicę. jest to przydatne do sortowania tablicy (lub przekonwertowanego obiektu na tablicę) według łańcucha:

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

Spróbuj tego. Nawet twój obiekt nie ma właściwości, na podstawie której próbujesz sortować, również zostanie obsłużony.

Po prostu wywołaj go, wysyłając właściwość z obiektem.

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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.