grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;
});
Zatem powyższy kod sortuje tablicę według gsize - od najmniejszej do największej. Działa dobrze. Ale jeśli gsize jest taki sam, chciałbym, żeby to sortował według blasku.
Dzięki.
javascript
arrays
znak
źródło
źródło
Odpowiedzi:
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; var aLow = a.glow; var bLow = b.glow; console.log(aLow + " | " + bLow); if(aSize == bSize) { return (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0; } else { return (aSize < bSize) ? -1 : 1; } });
źródło
grouperArray.sort(function (a, b) { return a.gsize - b.gsize || a.glow - b.glow; });
krótsza wersja
źródło
sort an array with a key's value first
a potemsort the result with another key's value
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);
Jeszcze krótsza wersja ze składnią strzałek!
źródło
grouperArray.sort((a,b)=>a.gsize-b.gsize||a.glow-b.glow);
Zdaję sobie sprawę, że pytano o to jakiś czas temu, ale pomyślałem, że dodam swoje rozwiązanie.
Ta funkcja dynamicznie generuje metody sortowania. po prostu podaj każdą możliwą do sortowania nazwę właściwości podrzędnej, poprzedzoną znakiem +/-, aby wskazać kolejność rosnącą lub malejącą. Super do ponownego użycia i nie musi nic wiedzieć o utworzonej strukturze danych. Można to uczynić idiotą - ale nie wydaje się konieczne.
function getSortMethod(){ var _args = Array.prototype.slice.call(arguments); return function(a, b){ for(var x in _args){ var ax = a[_args[x].substring(1)]; var bx = b[_args[x].substring(1)]; var cx; ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1; bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1; if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;} if(ax != bx){return ax < bx ? -1 : 1;} } } }
przykład użycia:
items.sort (getSortMethod ('- cena', '+ priorytet', '+ nazwa'));
posortowałoby to
items
od najniższej doprice
pierwszej, z powiązaniami prowadzącymi do pozycji o najwyższejpriority
. dalsze więzi są zrywane przez przedmiotname
gdzie elementy to tablica taka jak:
var items = [ { name: "z - test item", price: "99.99", priority: 0, reviews: 309, rating: 2 }, { name: "z - test item", price: "1.99", priority: 0, reviews: 11, rating: 0.5 }, { name: "y - test item", price: "99.99", priority: 1, reviews: 99, rating: 1 }, { name: "y - test item", price: "0", priority: 1, reviews: 394, rating: 3.5 }, { name: "x - test item", price: "0", priority: 2, reviews: 249, rating: 0.5 } ... ];
demo na żywo: http://gregtaff.com/misc/multi_field_sort/
EDYCJA: Naprawiono problem z Chrome.
źródło
error TS2554: Expected 0 arguments, but got ..
) użyj składni tutaj: stackoverflow.com/a/4116634/5287221Spodziewam się, że operator trójskładnikowy
((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;)
cię pomylił. Powinieneś sprawdzić link, aby lepiej go zrozumieć.Do tego czasu, oto twój kod wydmuchany w pełni if / else.
grouperArray.sort(function (a, b) { if (a.gsize < b.gsize) { return -1; } else if (a.gsize > b.gsize) { return 1; } else { if (a.glow < b.glow) { return -1; } else if (a.glow > b.glow) { return 1; } return 0; } });
źródło
Oto implementacja dla tych, którzy mogą chcieć czegoś bardziej ogólnego, który działałby z dowolną liczbą pól.
Array.prototype.sortBy = function (propertyName, sortDirection) { var sortArguments = arguments; this.sort(function (objA, objB) { var result = 0; for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) { var propertyName = sortArguments[argIndex]; result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0; //Reverse if sort order is false (DESC) result *= !sortArguments[argIndex + 1] ? 1 : -1; } return result; }); }
Zasadniczo możesz określić dowolną liczbę nazw właściwości / kierunku sortowania:
var arr = [{ LastName: "Doe", FirstName: "John", Age: 28 }, { LastName: "Doe", FirstName: "Jane", Age: 28 }, { LastName: "Foo", FirstName: "John", Age: 30 }]; arr.sortBy("LastName", true, "FirstName", true, "Age", false); //Will return Jane Doe / John Doe / John Foo arr.sortBy("Age", false, "LastName", true, "FirstName", false); //Will return John Foo / John Doe / Jane Doe
źródło
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; var aLow = a.glow; var bLow = b.glow; console.log(aLow + " | " + bLow); return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : ( (aLow < bLow ) ? -1 : (aLow > bLow ) ? 1 : 0 ); });
źródło
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; var aLow = a.glow; var bLow = b.glow; console.log(aLow + " | " + bLow); return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0); });
źródło
Oto implementacja, która używa rekurencji do sortowania według dowolnej liczby pól sortowania od 1 do nieskończoności. Przekazujesz mu tablicę wyników, która jest tablicą obiektów wynikowych do sortowania, oraz tablicę sortów, która jest tablicą obiektów sortowania definiujących sortowanie. Każdy obiekt sortowania musi mieć klucz „select” dla nazwy klucza, według którego sortuje, oraz klucz „order”, który jest łańcuchem oznaczającym „rosnąco” lub „malejąco”.
sortMultiCompare = (a, b, sorts) => { let select = sorts[0].select let order = sorts[0].order if (a[select] < b[select]) { return order == 'ascending' ? -1 : 1 } if (a[select] > b[select]) { return order == 'ascending' ? 1 : -1 } if(sorts.length > 1) { let remainingSorts = sorts.slice(1) return this.sortMultiCompare(a, b, remainingSorts) } return 0 } sortResults = (results, sorts) => { return results.sort((a, b) => { return this.sortMultiCompare(a, b, sorts) }) } // example inputs const results = [ { "LastName": "Doe", "FirstName": "John", "MiddleName": "Bill" }, { "LastName": "Doe", "FirstName": "Jane", "MiddleName": "Bill" }, { "LastName": "Johnson", "FirstName": "Kevin", "MiddleName": "Bill" } ] const sorts = [ { "select": "LastName", "order": "ascending" }, { "select": "FirstName", "order": "ascending" }, { "select": "MiddleName", "order": "ascending" } ] // call the function like this: let sortedResults = sortResults(results, sorts)
źródło
Dynamiczny sposób na zrobienie tego za pomocą WIELU klawiszy:
Object.defineProperty(Array.prototype, 'orderBy', { value: function(sorts) { sorts.map(sort => { sort.uniques = Array.from( new Set(this.map(obj => obj[sort.key])) ); sort.uniques = sort.uniques.sort((a, b) => { if (typeof a == 'string') { return sort.inverse ? b.localeCompare(a) : a.localeCompare(b); } else if (typeof a == 'number') { return sort.inverse ? (a < b) : (a > b ? 1 : 0); } else if (typeof a == 'boolean') { let x = sort.inverse ? (a === b) ? 0 : a? -1 : 1 : (a === b) ? 0 : a? 1 : -1; return x; } return 0; }); }); const weightOfObject = (obj) => { let weight = ""; sorts.map(sort => { let zeropad = `${sort.uniques.length}`.length; weight += sort.uniques.indexOf(obj[sort.key]).toString().padStart(zeropad, '0'); }); //obj.weight = weight; // if you need to see weights return weight; } this.sort((a, b) => { return weightOfObject(a).localeCompare( weightOfObject(b) ); }); return this; } });
Posługiwać się:
// works with string, number and boolean let sortered = your_array.orderBy([ {key: "type", inverse: false}, {key: "title", inverse: false}, {key: "spot", inverse: false}, {key: "internal", inverse: true} ]);
źródło
To jest to, czego używam
function sort(a, b) { var _a = "".concat(a.size, a.glow); var _b = "".concat(b.size, b.glow); return _a < _b; }
połącz oba elementy jako ciąg, a zostaną one posortowane według wartości ciągu. Jeśli chcesz, możesz zawinąć _a i _b parseInt, aby porównać je jako liczby, jeśli wiesz, że będą numeryczne.
źródło
Oto rozwiązanie dla przypadku, gdy masz priorytetowy klucz sortowania, który może nie istnieć w niektórych konkretnych elementach, więc musisz sortować według kluczy rezerwowych.
Przykład danych wejściowych ( id2 to priorytet sortowania klucza):
const arr = [ {id: 1}, {id: 2, id2: 3}, {id: 4}, {id: 3}, {id: 10, id2: 2}, {id: 7}, {id: 6, id2: 1}, {id: 5}, {id: 9, id2: 2}, {id: 8}, ];
Wynik powinien być:
[ { id: 6, id2: 1 }, { id: 9, id2: 2 }, { id: 10, id2: 2 }, { id: 2, id2: 3 }, { id: 1 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 7 }, { id: 8 } ]
Funkcja komparatora będzie wyglądać następująco:
arr.sort((a,b) => { if(a.id2 || b.id2) { if(a.id2 && b.id2) { if(a.id2 === b.id2) { return a.id - b.id; } return a.id2 - b.id2; } return a.id2 ? -1 : 1; } return a.id - b.id });
PS W przypadku, gdy .id z .id2 może być zerami, rozważ użycie
typeof
.źródło
grouperArray.sort( function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize} );
źródło
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; if (aSize !== aSize) return aSize - bSize; return a.glow - b.glow; });
nie testowane, ale myślę, że to powinno działać.
źródło
W moim przypadku sortuję listę powiadomień według parametru „ważne” i „daty”
krok 1: filtruję powiadomienia według „ważnych” i nieważnych
let importantNotifications = notifications.filter( (notification) => notification.isImportant); let unImportantNotifications = notifications.filter( (notification) => !notification.isImportant);
krok 2: sortuję je według daty
sortByDate = (notifications) => { return notifications.sort((notificationOne, notificationTwo) => { return notificationOne.date - notificationTwo.date; }); };
krok 3: scal je
źródło