Chłopaki jestem w szoku w przenośni! Oczywiście wszystkie odpowiedzi są nieco stare, ale nikt nawet nie wspomniał o stabilności sortowania! Więc proszę o cierpliwość, postaram się jak najlepiej odpowiedzieć na pytanie i przejść do szczegółów tutaj. Przepraszam, więc będzie dużo do przeczytania.
Ponieważ jest 2018, będę używać tylko ES6, wszystkie polifill są dostępne w dokumentach MDN, które podlinkuję w danej części.
Odpowiedz na pytanie:
Jeśli twoje klucze są tylko cyframi, możesz bezpiecznie użyć Object.keys()
razem z, Array.prototype.reduce()
aby zwrócić posortowany obiekt:
// Only numbers to show it will be sorted.
const testObj = {
'2000': 'Articel1',
'4000': 'Articel2',
'1000': 'Articel3',
'3000': 'Articel4',
};
// I'll explain what reduces does after the answer.
console.log(Object.keys(testObj).reduce((accumulator, currentValue) => {
accumulator[currentValue] = testObj[currentValue];
return accumulator;
}, {}));
/**
* expected output:
* {
* '1000': 'Articel3',
* '2000': 'Articel1',
* '3000': 'Articel4',
* '4000': 'Articel2'
* }
*/
// if needed here is the one liner:
console.log(Object.keys(testObj).reduce((a, c) => (a[c] = testObj[c], a), {}));
Jednak jeśli pracujesz z łańcuchami, bardzo polecam połączenie tego Array.prototype.sort()
wszystkiego:
// String example
const testObj = {
'a1d78eg8fdg387fg38': 'Articel1',
'z12989dh89h31d9h39': 'Articel2',
'f1203391dhj32189h2': 'Articel3',
'b10939hd83f9032003': 'Articel4',
};
// Chained sort into all of this.
console.log(Object.keys(testObj).sort().reduce((accumulator, currentValue) => {
accumulator[currentValue] = testObj[currentValue];
return accumulator;
}, {}));
/**
* expected output:
* {
* a1d78eg8fdg387fg38: 'Articel1',
* b10939hd83f9032003: 'Articel4',
* f1203391dhj32189h2: 'Articel3',
* z12989dh89h31d9h39: 'Articel2'
* }
*/
// again the one liner:
console.log(Object.keys(testObj).sort().reduce((a, c) => (a[c] = testObj[c], a), {}));
Jeśli ktoś zastanawia się, co robi redukcja:
// Will return Keys of object as an array (sorted if only numbers or single strings like a,b,c).
Object.keys(testObj)
// Chaining reduce to the returned array from Object.keys().
// Array.prototype.reduce() takes one callback
// (and another param look at the last line) and passes 4 arguments to it:
// accumulator, currentValue, currentIndex and array
.reduce((accumulator, currentValue) => {
// setting the accumulator (sorted new object) with the actual property from old (unsorted) object.
accumulator[currentValue] = testObj[currentValue];
// returning the newly sorted object for the next element in array.
return accumulator;
// the empty object {} ist the initial value for Array.prototype.reduce().
}, {});
W razie potrzeby znajduje się wyjaśnienie dla jednej wkładki:
Object.keys(testObj).reduce(
// Arrow function as callback parameter.
(a, c) =>
// parenthesis return! so we can safe the return and write only (..., a);
(a[c] = testObj[c], a)
// initial value for reduce.
,{}
);
Dlaczego sortowanie jest trochę skomplikowane:
W skrócie Object.keys()
zwróci tablicę o takiej samej kolejności, jak w przypadku normalnej pętli:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]
Object.keys () zwraca tablicę, której elementy są łańcuchami odpowiadającymi wyliczalnym właściwościom znalezionym bezpośrednio na obiekcie. Kolejność właściwości jest taka sama, jak podana przez ręczne zapętlenie właściwości obiektu.
Sidenote - możesz używać również Object.keys()
na tablicach, pamiętaj, że indeks zostanie zwrócony:
// simple array
const arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
Ale nie jest to tak łatwe, jak pokazano w tych przykładach, obiekty świata rzeczywistego mogą zawierać liczby i znaki alfabetyczne, a nawet symbole (nie rób tego).
Oto przykład z nimi wszystkimi w jednym obiekcie:
// This is just to show what happens, please don't use symbols in keys.
const testObj = {
'1asc': '4444',
1000: 'a',
b: '1231',
'#01010101010': 'asd',
2: 'c'
};
console.log(Object.keys(testObj));
// output: [ '2', '1000', '1asc', 'b', '#01010101010' ]
Teraz, jeśli użyjemy Array.prototype.sort()
tablicy powyżej zmiany danych wyjściowych:
console.log(Object.keys(testObj).sort());
// output: [ '#01010101010', '1000', '1asc', '2', 'b' ]
Oto cytat z dokumentów:
Metoda sort () sortuje elementy tablicy na miejscu i zwraca tablicę. Sortowanie niekoniecznie jest stabilne. Domyślna kolejność sortowania jest zgodna z ciągami znaków kodu Unicode.
Nie można zagwarantować złożoności czasowej i przestrzennej tego rodzaju, ponieważ zależy ona od implementacji.
Musisz upewnić się, że jeden z nich zwróci dla Ciebie żądane wyjście. W rzeczywistych przykładach ludzie mają tendencję do pomieszania rzeczy, szczególnie jeśli używasz różnych danych wejściowych, takich jak interfejsy API i bazy danych.
Więc o co chodzi?
Cóż, są dwa artykuły, które każdy programista powinien zrozumieć:
Algorytm lokalny :
W informatyce algorytm lokalny jest algorytmem, który przekształca dane wejściowe bez żadnej struktury danych pomocniczych. Jednak niewielka ilość dodatkowej przestrzeni dyskowej jest dozwolona dla zmiennych pomocniczych. Dane wejściowe są zwykle nadpisywane przez dane wyjściowe podczas wykonywania algorytmu. Algorytm lokalny aktualizuje sekwencję wprowadzania tylko poprzez zamianę lub zamianę elementów. Algorytm, który nie jest na miejscu, jest czasem nazywany „nie na miejscu” lub „na miejscu”.
Więc w zasadzie nasza stara tablica zostanie nadpisana! Jest to ważne, jeśli chcesz zachować starą tablicę z innych powodów. Miej to na uwadze.
Algorytm sortowania
Stabilne algorytmy sortowania sortują identyczne elementy w tej samej kolejności, w jakiej pojawiają się na wejściu. Podczas sortowania niektórych rodzajów danych, tylko część danych jest sprawdzana podczas określania kolejności sortowania. Na przykład w przykładzie sortowania kart po prawej stronie, karty są sortowane według ich rangi, a ich kolor jest ignorowany. Pozwala to na wiele różnych poprawnie posortowanych wersji oryginalnej listy. Stabilne algorytmy sortowania wybierają jeden z nich, zgodnie z następującą zasadą: jeśli dwa elementy będą porównywane jako równe, podobnie jak dwie 5 kart, to ich względna kolejność zostanie zachowana, tak że jeśli jedna pojawi się przed drugą na wejściu, to również pojawiają się przed innymi w wyniku.
Przykład stabilnego sortowania na kartach do gry. Kiedy karty są sortowane według rangi przy użyciu stabilnego sortowania, dwie 5 muszą pozostać w tej samej kolejności na posortowanym wyjściu, w którym były pierwotnie. Kiedy są sortowane z niestabilnym sortowaniem, 5 mogą skończyć odwrotnie kolejność w posortowanym wyjściu.
To pokazuje, że sortowanie jest prawidłowe, ale się zmieniło. Tak więc w prawdziwym świecie, nawet jeśli sortowanie jest prawidłowe, musimy upewnić się, że otrzymamy to, czego oczekujemy! To bardzo ważne, należy o tym pamiętać. Więcej przykładów JavaScript można znaleźć w Array.prototype.sort () - docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort