Z tego pierwotnego pytania , jak zastosować sortowanie na wielu polach?
Korzystając z tej nieco dostosowanej struktury, jak posortować miasto (rosnąco), a następnie cenę (malejąco)?
var homes = [
{"h_id":"3",
"city":"Dallas",
"state":"TX",
"zip":"75201",
"price":"162500"},
{"h_id":"4",
"city":"Bevery Hills",
"state":"CA",
"zip":"90210",
"price":"319250"},
{"h_id":"6",
"city":"Dallas",
"state":"TX",
"zip":"75000",
"price":"556699"},
{"h_id":"5",
"city":"New York",
"state":"NY",
"zip":"00010",
"price":"962500"}
];
Podobał mi się fakt, że otrzymałem odpowiedź, która zawierała ogólne podejście. Tam, gdzie planuję użyć tego kodu, będę musiał posortować daty i inne rzeczy. Możliwość „gruntowania” obiektu wydawała się przydatna, jeśli nie trochę kłopotliwa.
Próbowałem przekształcić tę odpowiedź w ładny ogólny przykład, ale nie mam szczęścia.
javascript
arrays
sorting
Mikrofon
źródło
źródło
sort(["first-field", "ASC"], ["second-field", "DSC"]);
że dodam morze kodu, kiedy po prostu chcę powiedzieć. Jest to jeszcze bardziej skomplikowane, gdy próbuję dodać logikę „podkładu” do pierwszej odpowiedzi, aby móc obsłużyć daty, rozróżnianie wielkości liter itp.Odpowiedzi:
Wielowymiarowa metoda sortowania oparta na tej odpowiedzi :
Aktualizacja : Oto wersja „zoptymalizowana”. Wykonuje dużo więcej wstępnego przetwarzania i tworzy wcześniej funkcję porównawczą dla każdej opcji sortowania. Może potrzebować więcej pamięci (ponieważ przechowuje funkcję dla każdej opcji sortowania, ale powinien działać trochę lepiej, ponieważ nie musi określać poprawnych ustawień podczas porównania. Nie wykonałem jednak żadnego profilowania.
Przykładowe użycie:
PRÓBNY
Oryginalna funkcja:
PRÓBNY
źródło
aby uzyskać nieogólne, proste rozwiązanie konkretnego problemu:
źródło
if
instrukcja nie ma sensu.a.localeCompare(b)
w ostatnim wierszu do porównania ciągów ... zobacz dokumentacjęif (a.city === b.city)
? Oznacza to, że jeśli oba miasta są takie same, porównaj ceny, w przeciwnym razie porównaj miasta.Możesz użyć metody sortowania łańcuchowego, biorąc deltę wartości, aż osiągnie wartość różną od zera.
Lub używając es6, po prostu:
źródło
Oto proste podejście funkcjonalne. Określ kolejność sortowania za pomocą tablicy. Dodaj minus na początku, aby określić kolejność malejącą.
Edycja: w ES6 jest jeszcze krócej!
źródło
[10,100,11,9]
. Przegapiłem coś?Zrobiłem dzisiaj dość ogólny sortownik wielu funkcji. Możesz rzucić okiem na thenBy.js tutaj: https://github.com/Teun/thenBy.js
Pozwala na użycie standardowego Array.sort, ale ze stylem firstBy (). ThenBy (). ThenBy (). Jest to o wiele mniej kodu i złożoności niż opisane powyżej rozwiązania.
źródło
Poniższa funkcja umożliwia sortowanie tablicy obiektów według jednej lub wielu właściwości, rosnąco (domyślnie) lub malejąco według każdej właściwości, i pozwala wybrać, czy mają być wykonywane porównania z uwzględnieniem wielkości liter. Domyślnie ta funkcja wykonuje sortowanie bez uwzględniania wielkości liter.
Pierwszym argumentem musi być tablica zawierająca obiekty. Kolejne argumenty muszą być listą ciągów oddzielonych przecinkami, które odwołują się do różnych właściwości obiektu do sortowania. Ostatni argument (który jest opcjonalny) jest wartością logiczną, która pozwala wybrać, czy sortować z
true
uwzględnieniem wielkości liter, czy nie - użyj go do sortowania z uwzględnieniem wielkości liter.Funkcja domyślnie posortuje każdą właściwość / klucz w porządku rosnącym. Jeśli chcesz konkretny klucz do sortowania w kolejności malejącej, a następnie zamiast przechodzić w tablicy w tym formacie:
['property_name', true]
.Oto kilka przykładowych zastosowań funkcji, po których następuje wyjaśnienie (gdzie
homes
jest tablicą zawierającą obiekty):objSort(homes, 'city')
-> sortuj według miasta (rosnąco, z uwzględnieniem wielkości liter)objSort(homes, ['city', true])
-> sortuj według miasta (malejąco, z uwzględnieniem wielkości liter)objSort(homes, 'city', true)
-> sortowanie wg miasta wówczas cena (rosnąco, sprawa wrażliwa )objSort(homes, 'city', 'price')
-> sortuj według miasta, a następnie ceny (zarówno rosnąco, z uwzględnieniem wielkości liter)objSort(homes, 'city', ['price', true])
-> sortuj według miasta (rosnąco), a następnie ceny (malejąco), z uwzględnieniem wielkości liter)I bez zbędnych ceregieli, oto funkcja:
A oto kilka przykładowych danych:
źródło
To kompletny oszustwo, ale myślę, że dodaje wartości do tego pytania, ponieważ jest to w zasadzie funkcja biblioteki w puszkach, z której można korzystać po wyjęciu z pudełka.
Jeśli twój kod ma dostęp
lodash
lub bibliotekę kompatybilną z lodash, jak na przykładunderscore
, możesz użyć tej_.sortBy
metody. Poniższy fragment kodu jest kopiowany bezpośrednio z dokumentacji lodash .Skomentowane wyniki w przykładach wyglądają tak, jakby zwracały tablice tablic, ale to tylko pokazuje kolejność, a nie rzeczywiste wyniki, które są tablicą obiektów.
źródło
Oto kolejny, być może bliższy Twojemu pomysłowi na składnię
Demo: http://jsfiddle.net/Nq4dk/2/
Edycja: dla zabawy, oto odmiana, która po prostu przyjmuje ciąg podobny do sql, więc możesz to zrobić
sortObjects(homes, "city, price desc")
źródło
Prostszy:
źródło
Podoba mi się podejście SnowBurnta, ale wymaga to poprawki, aby przetestować równoważność w mieście, a NIE różnicę.
źródło
Oto ogólne sortowanie wielowymiarowe, umożliwiające odwracanie i / lub mapowanie na każdym poziomie.
Napisane na maszynie. W przypadku JavaScript, sprawdź to JSFiddle
Kod
Przykłady użycia
Sortowanie tablicy osób według nazwiska, a następnie imienia:
Sortuj kody języków według nazwy , a nie kodu języka (zobacz
map
), a następnie według wersji malejącej (zobaczreverse
).źródło
Dynamiczny sposób na zrobienie tego za pomocą WIELU klawiszy:
Posługiwać się:
źródło
Oto ogólna wersja rozwiązania @ Snowburnt:
Jest to oparte na rutynie sortowania, której używam. Nie testowałem tego konkretnego kodu, więc może zawierać błędy, ale masz pomysł. Chodzi o to, aby posortować dane na podstawie pierwszego pola, które wskazuje na różnicę, a następnie zatrzymać się i przejść do następnego rekordu. Tak więc, jeśli sortujesz według trzech pól, a pierwsze pole w porównaniu wystarczy do określenia kolejności sortowania dwóch sortowanych rekordów, zwróć wynik sortowania i przejdź do następnego rekordu.
Przetestowałem to (właściwie z trochę bardziej złożoną logiką sortowania) na 5000 płyt i zrobiłem to w mgnieniu oka. Jeśli faktycznie ładujesz więcej niż 1000 rekordów do klienta, prawdopodobnie powinieneś używać sortowania i filtrowania po stronie serwera.
Ten kod nie obsługuje rozróżniania wielkości liter, ale pozostawiam czytelnikowi obsługę tej trywialnej modyfikacji.
źródło
Oto moje rozwiązanie oparte na idiomie transformacji Schwartza , mam nadzieję, że uznasz je za przydatne.
Oto przykład, jak go używać:
źródło
Inny sposób
źródło
Jak używać (wstaw - (minus) znak przed polem, jeśli chcesz posortować w kolejności malejącej poszczególne pola)
Korzystając z powyższej funkcji, możesz sortować dowolną tablicę json z wieloma polami. W ogóle nie ma potrzeby zmiany ciała funkcji
źródło
Adaptacja odpowiedzi @chriskelly.
Większość odpowiedzi pomija fakt, że cena nie zostanie prawidłowo posortowana, jeśli wartość będzie wynosić dziesięć tysięcy i mniej lub ponad milion. Rezonans JS sortuje alfabetycznie. Tutaj odpowiedź była całkiem dobra. Dlaczego JavaScript nie może sortować "5, 10, 1" i tutaj Jak poprawnie posortować tablicę liczb całkowitych .
Ostatecznie musimy dokonać oceny, jeśli pole lub węzeł, według którego sortujemy, jest liczbą. Nie mówię, że użycie
parseInt()
w tym przypadku jest poprawną odpowiedzią, ważniejsze są posortowane wyniki.Skrzypce do przetestowania
źródło
price
w przykładzie jest w formacie ciągu. Jeśli chcesz, aby działało poprawnie z moim przykładem, użyj mapy, aby najpierw przekonwertować pole, które chcesz sformatować. ieconst correctedHomes = homes.map(h => ({...h, price: +h.price}))
Wow, są tutaj złożone rozwiązania. Tak skomplikowane, że postanowiłem wymyślić coś prostszego, ale też dość potężnego. Tutaj jest;
A oto przykład tego, jak go używasz.
Spowoduje to najpierw sortowanie według pierwszeństwa atrybutów, a następnie według wartości atrybutów.
źródło
Oto rozszerzalny sposób sortowania według wielu pól.
Uwagi
a.localeCompare(b)
jest powszechnie obsługiwana i wraca -1,0,1 jeślia<b
,a==b
,a>b
odpowiednio.||
w ostatniej linii dajecity
pierwszeństwoprice
.-price_order
var date_order = new Date(left.date) - new Date(right.date);
działa jak numerycznych ponieważ data matematyki zamienia się w milisekundach od 1970 roku.return city_order || -price_order || date_order;
źródło
Myślę, że to może być najłatwiejszy sposób na zrobienie tego.
https://coderwall.com/p/ebqhca/javascript-sort-by-two-fields
To naprawdę proste i wypróbowałem je z 3 różnymi parami klucz-wartość i działało świetnie.
Oto prosty przykład, spójrz na link, aby uzyskać więcej informacji
źródło
Oto moje w celach informacyjnych, z przykładem:
źródło
Szukałem czegoś podobnego i skończyło się na tym:
Najpierw mamy jedną lub więcej funkcji sortujących, zawsze zwracających 0, 1 lub -1:
Możesz utworzyć więcej funkcji dla każdej innej właściwości, według której chcesz sortować.
Następnie mam funkcję, która łączy te funkcje sortowania w jedną:
Można to wykorzystać do połączenia powyższych funkcji sortowania w czytelny sposób:
Gdy funkcja sortowania zwróci 0, zostanie wywołana następna funkcja sortowania w celu dalszego sortowania.
źródło
Po prostu inna opcja. Rozważ użycie następującej funkcji narzędzia:
Przykład użycia (w Twoim przypadku):
Należy zauważyć, że tę funkcję można jeszcze bardziej uogólnić, aby móc używać zagnieżdżonych właściwości, takich jak „address.city” lub „style.size.width” itp.
źródło
Jest to algorytm rekurencyjny do sortowania według wielu pól z możliwością formatowania wartości przed porównaniem.
Jeśli a i b są równe, po prostu spróbuje przejść do następnego pola, aż żadne nie będzie dostępne.
źródło
źródło
Tutaj „AffiliateDueDate” i „Title” są kolumnami, obie są posortowane w kolejności rosnącej.
źródło
Sortowanie według dwóch pól daty i przykład pola liczbowego:
http://jsfiddle.net/hcWgf/57/
źródło
Za pomocą :
Pokaż fragment kodu
źródło
A co z tym prostym rozwiązaniem:
Na podstawie tego pytania javascript sortuj tablicę według wielu pól (liczb)
źródło