[英]Sort array of objects based on multiple properties
I'm trying to sort array of objects based on arbitrary property inside the object. 我正在尝试根据对象内部的任意属性对对象数组进行排序。 I wrote the following code which works perfectly. 我写了下面的代码,效果很好。
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 here: JSFiddle 小提琴在这里: JSFiddle
Now, I'm trying to use recursion to have sort by multiple properties in following manner: First, sort by first property and then within that same property, sort by second property, and so on. 现在,我尝试使用递归以以下方式对多个属性进行排序:首先,按第一个属性排序,然后在同一属性内,按第二个属性排序,依此类推。 For keeping things simple, I'm assuming same order for all the properties, ie either all increasing or all decreasing. 为了简单起见,我假设所有属性的顺序相同,即全部递增或全部递减。
I wrote this code: 我写了这段代码:
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']));
Fiddle here: JSFiddle 小提琴在这里: JSFiddle
Unfortunately, I couldn't make it work. 不幸的是,我无法使其工作。 What am I missing here? 我在这里想念什么?
sortBy.shift(); nestedSort();
is your problem. 是你的问题。 shift
does mutate the array, and drop the first item forever. shift
会改变数组,并永久删除第一项。 The next time the comparison function is called to compare a
with b
, it will be ignored, and soon the array will be empty and your comparsion breaks completely. 下次调用比较函数将a
与b
进行比较时,它将被忽略,并且很快数组将为空并且您的比较完全中断。
Instead, use a simple loop: 而是使用一个简单的循环:
return data.sort(function(a, b) {
for (var i=0; i<sortBy.length; i++)
var currentOrder = sortBy[i];
var A = parse(a, currentOrder);
var B = parse(b, currentOrder);
if (A < B) {
return order === 'asc' ? -1 : 1;
} else if (A > B) {
return order === 'asc' ? 1 : -1;
}
}
return 0;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.