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
};
Steerpike
źródło
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]
})
Nosredna
źródło
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

Markus R.
źródło
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/

inorganik
źródło
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.

Stano
źródło
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]]
pływanie
źródło
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!

Jason J. Nathan
źródło
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.

NickFitz
źródło
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

Alireza
źródło
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}
Wasil Nikołow
źródło
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
julianljk
źródło
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

Roman Judin
źródło
6

Bardzo krótki i prosty!

var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
    sortedList[key] = list[key]; });
Maryam Koulaei
źródło
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
}
bonna
źródło
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) 

dino4udo
źródło
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)
Carson Wright
źródło
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}]

Kiran Debnath
źródło
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}
Esneyderp
źródło
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 ] ]
Remi Prasanna
źródło
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;
}
Shimon Doodkin
źródł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;
}
victorhazbun
źródło
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);

Mahendra Kulkarni
źródło
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
źródło
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 });
orad
źródło
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));
James T.
źródło
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
źródło
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]);
}
Ivan Bozveliev
źródło
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>
Chirag Modi
źródło
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

vivek_nk
źródło
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
Furia
źródło
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;
}
Vali Shah
źródło