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;
});
Таким образом, приведенный выше код сортирует массив по gsize - от наименьшего к наибольшему. Работает хорошо. Но если размер такой же, я бы хотел отсортировать его по свечению.
Спасибо.
javascript
arrays
отметка
источник
источник
Ответы:
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; } });
источник
grouperArray.sort(function (a, b) { return a.gsize - b.gsize || a.glow - b.glow; });
более короткая версия
источник
sort an array with a key's value first
а потомsort the result with another key's value
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);
Еще более короткая версия с использованием синтаксиса стрелок!
источник
grouperArray.sort((a,b)=>a.gsize-b.gsize||a.glow-b.glow);
Я понимаю, что это было задано некоторое время назад, но я подумал, что добавлю свое решение.
Эта функция динамически генерирует методы сортировки. просто укажите имя каждого сортируемого дочернего свойства с добавлением +/-, чтобы указать возрастающий или убывающий порядок. Очень многоразовый, и ему не нужно ничего знать о структуре данных, которую вы собрали. Можно сделать идиотское доказательство - но в этом нет необходимости.
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;} } } }
пример использования:
items.sort (getSortMethod ('- цена', '+ приоритет', '+ имя'));
это будет сортировать
items
с наименьшимprice
первым, с привязкой к элементу с наибольшимpriority
. дальнейшие связи разрываются товаромname
где items - это массив вроде:
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 } ... ];
живая демонстрация: http://gregtaff.com/misc/multi_field_sort/
РЕДАКТИРОВАТЬ: исправлена проблема с Chrome.
источник
error TS2554: Expected 0 arguments, but got ..
) используйте синтаксис здесь: stackoverflow.com/a/4116634/5287221Я думаю, что тернарный оператор
((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;)
вас запутал. Вы должны проверить ссылку, чтобы лучше понять это.А пока вот ваш код полностью продуман 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; } });
источник
Вот реализация для тех, кому может понадобиться что-то более общее, работающее с любым количеством полей.
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; }); }
По сути, вы можете указать любое количество названий свойств / направлений сортировки:
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
источник
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 ); });
источник
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); });
источник
Вот реализация, которая использует рекурсию для сортировки по любому количеству полей сортировки от 1 до бесконечности. Вы передаете ему массив результатов, который представляет собой массив объектов результата для сортировки, и массив сортировки, который представляет собой массив объектов сортировки, определяющих сортировку. Каждый объект сортировки должен иметь ключ «select» для имени ключа, по которому он сортирует, и ключ «order», который представляет собой строку, указывающую «по возрастанию» или «по убыванию».
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)
источник
Динамический способ сделать это с НЕСКОЛЬКИМИ клавишами:
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; } });
Использование:
// 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} ]);
источник
Это то, что я использую
function sort(a, b) { var _a = "".concat(a.size, a.glow); var _b = "".concat(b.size, b.glow); return _a < _b; }
объедините два элемента в виде строки, и они будут отсортированы по строковому значению. Если вы хотите, вы можете заключить _a и _b в parseInt, чтобы сравнить их как числа, если вы знаете, что они будут числовыми.
источник
Вот решение для случая, когда у вас есть приоритетный ключ сортировки, который может не существовать в некоторых конкретных элементах, поэтому вам нужно сортировать по резервным ключам.
Пример входных данных ( id2 - приоритетный ключ сортировки):
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}, ];
И вывод должен быть:
[ { 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 } ]
Функция компаратора будет такой:
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 В случае, если .id из .id2 могут быть нулями, рассмотрите возможность использования
typeof
.источник
grouperArray.sort( function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize} );
источник
grouperArray.sort(function (a, b) { var aSize = a.gsize; var bSize = b.gsize; if (aSize !== aSize) return aSize - bSize; return a.glow - b.glow; });
не проверял, но думаю, что должно работать.
источник
В моем случае я сортирую список уведомлений по параметру "важно" и по "дате".
Шаг 1. Я фильтрую уведомления по «важным» и «неважным»
let importantNotifications = notifications.filter( (notification) => notification.isImportant); let unImportantNotifications = notifications.filter( (notification) => !notification.isImportant);
шаг 2: я сортирую их по дате
sortByDate = (notifications) => { return notifications.sort((notificationOne, notificationTwo) => { return notificationOne.date - notificationTwo.date; }); };
шаг 3: объедините их
источник