Я пытаюсь сортировать массив объектов на основе произвольного свойства внутри объекта. Я написал следующий код, который отлично работает.
Сортировка массива объектов на основе нескольких свойств
var customSort = function(data, sortBy, order) {
if (!(data && sortBy)) {
throw new Error('Specify the data source and atleast one property to sort it by');
}
if (!Array.isArray(data)) {
throw new Error('Specify the data source as an array');
}
order = order || 'asc';
function performSort(order, sortBy) {
return data.sort(function(a, b) {
var A = parse(a, sortBy);
var B = parse(b, sortBy);
if (A < B) {
return order === 'asc' ? -1 : 1;
} else if (A > B) {
return order === 'asc' ? 1 : -1;
} else {
return 0;
}
});
}
function parse(data, sortBy) {
var sortParams = sortBy.split('.');
var latestValue = data;
for (var i = 0; i < sortParams.length; i++) {
latestValue = latestValue[sortParams[i]];
}
if (!latestValue) {
throw new Error('Check the \'sortBy\' parameter. Unreachable parameter in \'sortBy\'');
}
if (typeof latestValue === 'string') {
return latestValue.toLowerCase();
} else {
return latestValue;
}
}
return performSort(order, sortBy);
};
var lonelyData = [{
a: {
b: 2
}
}, {
a: {
b: 1
}
}, {
a: {
b: 9
}
}, {
a: {
b: 7
}
}, {
a: {
b: 4
}
}, {
a: {
b: 2
}
}, {
a: {
b: 1
}
}];
console.log(customSort(lonelyData, 'a.b'));
Fiddle здесь: JSFiddle
Теперь я пытаюсь использовать рекурсию, чтобы сортировать по нескольким свойствам в следующим образом: Во-первых, сортировать по первому свойству, а затем в той же собственности , сортировать по второму свойству и т. д. Для упрощения вещей я принимаю одинаковый порядок для всех свойств, т. Е. Все возрастающие или все уменьшающиеся.
Я написал этот код:
var customSort = function(data, sortBy, order) {
if (!(data && sortBy)) {
throw new Error('Specify the data source and atleast one property to sort it by');
}
if (!Array.isArray(data)) {
throw new Error('Specify the data source as an array');
}
if (!Array.isArray(sortBy)) {
sortBy = [sortBy];
}
order = order || 'asc';
function performSort(order, sortBy) {
return data.sort(function(a, b) {
function nestedSort() {
var highestOrder = sortBy[0];
var A = parse(a, highestOrder);
var B = parse(b, highestOrder);
if (A < B) {
return order === 'asc' ? -1 : 1;
} else if (A > B) {
return order === 'asc' ? 1 : -1;
} else {
sortBy.shift();
nestedSort();
}
}
return nestedSort();
});
}
function parse(data, sortBy) {
var sortParams = sortBy.split('.');
var latestValue = data;
for (var i = 0; i < sortParams.length; i++) {
latestValue = latestValue[sortParams[i]];
}
if (!latestValue) {
throw new Error('Check the \'sortBy\' parameter. Unreachable property passed in \'sortBy\'');
}
if (typeof latestValue === 'string') {
return latestValue.toLowerCase();
} else {
return latestValue;
}
}
return performSort(order, sortBy);
};
var lonelyData = [{
a: {
b: 2,
c: 'Z'
}
}, {
a: {
b: 2,
c: 'A'
}
}, {
a: {
b: 9,
c: 'Q'
}
}, {
a: {
b: 7,
c: 'L'
}
}, {
a: {
b: 7,
c: 'E'
}
}, {
a: {
b: 1,
c: 'A'
}
}, {
a: {
b: 1,
c: 'B'
}
}];
console.log(customSort(lonelyData, ['a.b', 'a.c']));
скрипку здесь: JSFiddle
К сожалению, я не мог заставить его работать. Что мне здесь не хватает?
немного запутался здесь .... если SortBy есть [a.b, a.c], то вы хотите, чтобы массив будет отсортирован по порядку, а затем сортируются в алфавитном порядке? –
@ LucasKot-Zaniewski Если sortBy является [a.b, a.c], тогда массив должен сортироваться численно (на основе a.b), а затем для тех же значений чисел (a.b), массив должен быть отсортирован в алфавитном порядке (на основе a.c). Например, это должно выглядеть так: [{a: {b: 1, c: 'A'}}, {a: {b: 1, c: 'B'}}, {a: {b: 2, c : 'A'}}, {a: {b: 2, c: 'Z'}} ....... так далее] для вышеуказанного тестового примера – Ozil