Как отсортировать массив объектов с несколькими значениями полей в JavaScript
Я нашел отличный метод для сортировки массива объектов на основе одного из свойств, как определено в:
Сортировка массива объектов по значению свойства строки в JavaScript
Использование этой функции отлично работает для одного сортировки (во всех браузерах) и даже для сортировки в другом классе EXCEPT с помощью Google Chrome! Здесь Ege Özcan отличная процедура сортировки для массивов объектов
function dynamicSort(property) {
return function (a,b) {
return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
}
}
Использование массива с именем "Данные" (конечно, у моего массива много пар объектов)...
var Data = [{Category: "Business", Value: "ABC"},{Category:"Personal", Value:"XYZ"}];
Я могу получить правильный вид, где порядок указан как все значения в каждой категории, делая это...
Data.sort(dynamicSort("Value"));
Data.sort(dynamicSort("Category"));
Сначала сортируя по Value
, а затем по Category
, мой массив помещает все значения в порядке сортировки со всеми перечисленными выше значениями бизнес-базы, а затем всеми значениями на основе персонажа. Отлично! За исключением Chrome, где данные сортируются должным образом по категориям, но порядок значений в каждой категории кажется довольно случайным.
Знает ли кто-нибудь лучший способ сделать сортировку в сортировке, которая также будет работать в Chrome?
Ответы
Ответ 1
Я создал многопараметрическую версию этой функции dynamicSort:
function dynamicSort(property) {
return function (obj1,obj2) {
return obj1[property] > obj2[property] ? 1
: obj1[property] < obj2[property] ? -1 : 0;
}
}
function dynamicSortMultiple() {
/*
* save the arguments object as it will be overwritten
* note that arguments object is an array-like object
* consisting of the names of the properties to sort by
*/
var props = arguments;
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length;
/* try getting a different result from 0 (equal)
* as long as we have extra properties to compare
*/
while(result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
}
}
Я создал массив следующим образом:
var arr = [
{a:"a",b:"a",c:"a"},
{a:"b",b:"a",c:"b"},
{a:"b",b:"a",c:"a"},
{a:"b",b:"a",c:"b"},
{a:"b",b:"b",c:"a"},
{a:"b",b:"b",c:"b"},
{a:"b",b:"b",c:"a"},
{a:"b",b:"b",c:"b"},
{a:"b",b:"b",c:"a"},
{a:"b",b:"b",c:"b"},
{a:"b",b:"b",c:"a"},
{a:"c",b:"b",c:"b"},
{a:"c",b:"c",c:"a"}
];
и он работал, когда я это делал,
arr.sort(dynamicSortMultiple("c","b","a"));
И вот рабочий пример: http://jsfiddle.net/ZXedp/
Ответ 2
Самый простой способ выполнить сортировку нескольких критериев Javascript (или сортировку нескольких параметров) - использовать .sort
, объединить несколько параметров вместе и сравнить два укуса.
Например:
data.sort(function (a, b) {
var aConcat = a["property1"] + a["property2"];
var bConcat = b["property1"] + b["property2"];
if (aConcat > bConcat) {
return 1;
} else if (aConcat < bConcat) {
return -1;
} else {
return 0;
}
});
Я включил JsFiddle Script здесь: http://jsfiddle.net/oahxg4u3/6/
Ответ 3
Вы также можете посмотреть на thenBy.js: https://github.com/Teun/thenBy.js
Он позволяет использовать стандартный массив Array.sort, но с использованием метода firstBy(). thenBy(). thenBy().
Ответ 4
Я теперь этот пост довольно старый, так или иначе, я нашел его сегодня и цитируя Ege Özcan, я улучшил его отличное решение, реализующее функциональность DESC-ASC SQL-Like для всех, кого интересует (http://jsfiddle.net/ZXedp/65/):
function dynamicSortMultiple() {
var props=[];
/*Let separate property name from ascendant or descendant keyword*/
for(var i=0; i < arguments.length; i++){
var splittedArg=arguments[i].split(/ +/);
props[props.length]=[splittedArg[0], (splittedArg[1] ? splittedArg[1].toUpperCase() : "ASC")];
}
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length ;
/*Cycle on values until find a difference!*/
while(result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i][0], props[i][1])(obj1, obj2);
i++;
}
return result;
}
}
/*Base function returning -1,1,0 for custom sorting*/
function dynamicSort(property, isAscDesc) {
return function (obj1,obj2) {
if(isAscDesc==="DESC"){
return ((obj1[property] > obj2[property]) ? (-1) : ((obj1[property] < obj2[property]) ? (1) : (0)));
}
/*else, if isAscDesc==="ASC"*/
return ((obj1[property] > obj2[property]) ? (1) : ((obj1[property] < obj2[property]) ? (-1) : (0)));
}
}
вызвать функцию следующим образом:
arr.sort(dynamicSortMultiple("c DESC","b Asc","a"));
Ответ 5
Вот мое решение. Это быстрее, чем lodash _. SortBy() функция сортировки нескольких столбцов примерно в два раза (см. http://jsperf.com/multi-column-sort.
Я генерирую текст функции сортировки, а затем использую его в стандартном .sort(). Он также работает в Chrome и Firefox.
function multiColumnSort(arr,sf) {
var s = '';
sf.forEach(function(f,idx) {
s += 'if(arguments[0].'+f+'>arguments[1].'+f+')return 1;';
s += 'else if(arguments[0].'+f+'==arguments[1].'+f+')';
s += (idx < sf.length-1)? '{' : 'return 0';
});
s += Array(sf.length).join('}')+';return -1';
return arr.sort(new Function(s));
};