假设你有一个这样的JavaScript类
var DepartmentFactory = function(data) {
this.id = data.Id;
this.name = data.DepartmentName;
this.active = data.Active;
}
假设您随后创建了该类的许多实例,并将它们存储在一个数组中
var objArray = [];
objArray.push(DepartmentFactory({Id: 1, DepartmentName: 'Marketing', Active: true}));
objArray.push(DepartmentFactory({Id: 2, DepartmentName: 'Sales', Active: true}));
objArray.push(DepartmentFactory({Id: 3, DepartmentName: 'Development', Active: true}));
objArray.push(DepartmentFactory({Id: 4, DepartmentName: 'Accounting', Active: true}));
现在我将拥有一个由DepartmentFactory创建的对象数组。如何使用array.sort()方法按每个对象的DepartmentName属性对这个对象数组进行排序?
array.sort()方法在对字符串数组排序时工作得很好
var myarray=["Bob", "Bully", "Amy"];
myarray.sort(); //Array now becomes ["Amy", "Bob", "Bully"]
但是我如何让它与对象列表一起工作呢?
这是一个简单的函数,你可以用它来排序数组对象的属性;不管属性是字符串类型还是整数类型,它都可以工作。
var cars = [
{make:"AMC", model:"Pacer", year:1978},
{make:"Koenigsegg", model:"CCGT", year:2011},
{make:"Pagani", model:"Zonda", year:2006},
];
function sortObjectsByProp(objectsArr, prop, ascending = true) {
let objectsHaveProp = objectsArr.every(object => object.hasOwnProperty(prop));
if(objectsHaveProp) {
let newObjectsArr = objectsArr.slice();
newObjectsArr.sort((a, b) => {
if(isNaN(Number(a[prop]))) {
let textA = a[prop].toUpperCase(),
textB = b[prop].toUpperCase();
if(ascending) {
return textA < textB ? -1 : textA > textB ? 1 : 0;
} else {
return textB < textA ? -1 : textB > textA ? 1 : 0;
}
} else {
return ascending ? a[prop] - b[prop] : b[prop] - a[prop];
}
});
return newObjectsArr;
}
return objectsArr;
}
let sortedByMake = sortObjectsByProp(cars, "make"); // returns ascending order by its make;
let sortedByYear = sortObjectsByProp(cars, "year", false); // returns descending order by its year,since we put false as a third argument;
console.log(sortedByMake);
console.log(sortedByYear);
这是一个简单的函数,你可以用它来排序数组对象的属性;不管属性是字符串类型还是整数类型,它都可以工作。
var cars = [
{make:"AMC", model:"Pacer", year:1978},
{make:"Koenigsegg", model:"CCGT", year:2011},
{make:"Pagani", model:"Zonda", year:2006},
];
function sortObjectsByProp(objectsArr, prop, ascending = true) {
let objectsHaveProp = objectsArr.every(object => object.hasOwnProperty(prop));
if(objectsHaveProp) {
let newObjectsArr = objectsArr.slice();
newObjectsArr.sort((a, b) => {
if(isNaN(Number(a[prop]))) {
let textA = a[prop].toUpperCase(),
textB = b[prop].toUpperCase();
if(ascending) {
return textA < textB ? -1 : textA > textB ? 1 : 0;
} else {
return textB < textA ? -1 : textB > textA ? 1 : 0;
}
} else {
return ascending ? a[prop] - b[prop] : b[prop] - a[prop];
}
});
return newObjectsArr;
}
return objectsArr;
}
let sortedByMake = sortObjectsByProp(cars, "make"); // returns ascending order by its make;
let sortedByYear = sortObjectsByProp(cars, "year", false); // returns descending order by its year,since we put false as a third argument;
console.log(sortedByMake);
console.log(sortedByYear);
因为这里给出的所有解决方案都没有null/undefined安全操作,所以我用这种方式处理(你可以根据自己的需要处理null):
ES5
objArray.sort(
function(a, b) {
var departmentNameA = a.DepartmentName ? a.DepartmentName : '';
var departmentNameB = b.DepartmentName ? b.DepartmentName : '';
departmentNameA.localeCompare(departmentNameB);
}
);
ES6+
objArray.sort(
(a: DepartmentFactory, b: DepartmentFactory): number => {
const departmentNameA = a.DepartmentName ? a.DepartmentName : '';
const departmentNameB = b.DepartmentName ? b.DepartmentName : '';
departmentNameA.localeCompare(departmentNameB);
}
);
我还删除了其他人使用的toLowerCase,因为localeCompare是不区分大小写的。另外,在使用Typescript或ES6+时,我更喜欢在参数上更明确一点,以便对未来的开发人员更明确。