Javascript 基于多个属性对对象数组进行排序
我试图根据对象内部的任意属性对对象数组进行排序。 我编写了下面的代码,它工作得非常好。Javascript 基于多个属性对对象数组进行排序,javascript,arrays,object,recursion,javascript-objects,Javascript,Arrays,Object,Recursion,Javascript Objects,我试图根据对象内部的任意属性对对象数组进行排序。 我编写了下面的代码,它工作得非常好。 var customSort=函数(数据、排序、顺序){ 如果(!(数据和排序)){ 抛出新错误('指定数据源和至少一个属性进行排序'); } 如果(!Array.isArray(数据)){ 抛出新错误(“将数据源指定为数组”); } 订单=订单| |‘asc’; 功能performSort(订单、排序){ 返回数据。排序(函数(a,b){ var A=解析(A,sortBy); var B=解析(B,so
var customSort=函数(数据、排序、顺序){
如果(!(数据和排序)){
抛出新错误('指定数据源和至少一个属性进行排序');
}
如果(!Array.isArray(数据)){
抛出新错误(“将数据源指定为数组”);
}
订单=订单| |‘asc’;
功能performSort(订单、排序){
返回数据。排序(函数(a,b){
var A=解析(A,sortBy);
var B=解析(B,sortBy);
if(AB){
退货订单=='asc'?1:-1;
}否则{
返回0;
}
});
}
函数解析(数据,排序){
var sortParams=排序方式拆分('.');
var latestValue=数据;
对于(变量i=0;i
在这里拉小提琴:
现在,我尝试使用递归以如下方式对多个属性进行排序:首先,按第一个属性排序,然后在同一个属性内,按第二个属性排序,依此类推。为了简单起见,我假设所有属性的顺序都相同,即要么全部递增,要么全部递减。
我编写了以下代码:
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']));
var customSort=函数(数据、排序、顺序){
如果(!(数据和排序)){
抛出新错误('指定数据源和至少一个属性进行排序');
}
如果(!Array.isArray(数据)){
抛出新错误(“将数据源指定为数组”);
}
if(!Array.isArray(sortBy)){
sortBy=[sortBy];
}
订单=订单| |‘asc’;
功能performSort(订单、排序){
返回数据。排序(函数(a,b){
函数nestedSort(){
var highestOrder=sortBy[0];
var A=解析(A,高阶);
var B=解析(B,高阶);
if(AB){
退货订单=='asc'?1:-1;
}否则{
sortBy.shift();
嵌套排序();
}
}
返回nestedSort();
});
}
函数解析(数据,排序){
var sortParams=排序方式拆分('.');
var latestValue=数据;
对于(变量i=0;i
在这里拉小提琴:
不幸的是,我不能让它工作。我错过了什么 这是你的问题
shift
会改变数组,并永远删除第一项。下次调用比较函数来比较a
和b
,它将被忽略,很快数组将为空,比较将完全中断
相反,使用一个简单的循环:
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;
});
返回数据。排序(函数(a,b){
对于(变量i=0;i B){
退货订单=='asc'?1:-1;
}
}
返回0;
});
这里有点混乱……如果排序比是[A.b,A.c],那么您希望数组按数字排序,然后按字母顺序排序?@LucasKot Zaniewski如果排序比是[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'}等等]对于上面的测试用例,非常感谢。它工作得很好。然而,它也可以递归吗?当然,只要在i
上递归即可。或者通过数组和.slice(1)
循环执行排序,以获得不带第一个元素的副本。别忘了你的基本情况!
sortBy.shift();
nestedSort();
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;
});