我有一个JavaScript对象数组:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
如何在JavaScript中按last_nom的值对它们进行排序?
我知道排序(a,b),但这似乎只适用于字符串和数字。是否需要向对象添加toString()方法?
一个按属性对对象数组进行排序的简单函数:
function sortArray(array, property, direction) {
direction = direction || 1;
array.sort(function compare(a, b) {
let comparison = 0;
if (a[property] > b[property]) {
comparison = 1 * direction;
} else if (a[property] < b[property]) {
comparison = -1 * direction;
}
return comparison;
});
return array; // Chainable
}
用法:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
sortArray(objs, "last_nom"); // Asc
sortArray(objs, "last_nom", -1); // Desc
这是我的看法:
order参数是可选的,对于升序,默认为“ASC”。
它适用于重音字符,并且不区分大小写。
注意:它排序并返回原始数组。
function sanitizeToSort(str) {
return str
.normalize('NFD') // Remove accented and diacritics
.replace(/[\u0300-\u036f]/g, '') // Remove accented and diacritics
.toLowerCase() // Sort will be case insensitive
;
}
function sortByProperty(arr, property, order="ASC") {
arr.forEach((item) => item.tempProp = sanitizeToSort(item[property]));
arr.sort((a, b) => order === "ASC" ?
a.tempProp > b.tempProp ? 1 : a.tempProp < b.tempProp ? -1 : 0
: a.tempProp > b.tempProp ? -1 : a.tempProp < b.tempProp ? 1 : 0
);
arr.forEach((item) => delete item.tempProp);
return arr;
}
一小条
函数cleaniteToSort(str){返回str.normalize('NFD')//删除重音字符.replace(/[\u0300-\u036f]/g,“”)//删除变音符号.to小写();}函数sortByProperty(arr,property,order=“ASC”){arr.forEach((item)=>item.tempProp=消毒排序(item[property]));arr.sort((a,b)=>顺序==“ASC”?a.tempProp>b.tempProp?1:a.tempProp<b.tempProp-1 : 0:a.tempProp>b.tempProp-1:a.tempProp<b.tempProp?1 : 0);arr.forEach((item)=>删除item.tempProp);返回arr;}常量rockStars=[{name:“Axl”,姓:“Rose”},{name:“埃尔顿”,姓:“John”},{name:“Paul”,姓氏:“McCartney”},{name:“楼”,姓:“里德”},{name:“freddie”,//使用小写/大写姓氏:“mercury”},{name:“Ámy”,//也适用于重音字符姓氏:“酒庄”}];sortByProperty(rockStars,“name”);console.log(“按名称A-Z排序:”);rockStars.forEach((item)=>console.log(item.name+“”+item.lastname));sortByProperty(rockStars,“姓氏”,“DESC”);console.log(“\n按姓氏Z-A排序:”);rockStars.forEach((item)=>console.log(item.lastname+“,”+item.name));
使用原型继承简单快速地解决此问题:
Array.prototype.sortBy = function(p) {
return this.slice(0).sort(function(a,b) {
return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
});
}
示例/用法
objs = [{age:44,name:'vinay'},{age:24,name:'deepak'},{age:74,name:'suresh'}];
objs.sortBy('age');
// Returns
// [{"age":24,"name":"deepak"},{"age":44,"name":"vinay"},{"age":74,"name":"suresh"}]
objs.sortBy('name');
// Returns
// [{"age":24,"name":"deepak"},{"age":74,"name":"suresh"},{"age":44,"name":"vinay"}]
更新:不再修改原始数组。
我刚刚增强了EgeÖzcan的动态分类,可以深入物体内部。
如果数据如下所示:
obj = [
{
a: { a: 1, b: 2, c: 3 },
b: { a: 4, b: 5, c: 6 }
},
{
a: { a: 3, b: 2, c: 1 },
b: { a: 6, b: 5, c: 4 }
}];
如果你想在a.a属性中进行排序,我认为我的增强功能非常有用。我向以下对象添加了新功能:
Object.defineProperty(Object.prototype, 'deepVal', {
enumerable: false,
writable: true,
value: function (propertyChain) {
var levels = propertyChain.split('.');
parent = this;
for (var i = 0; i < levels.length; i++) {
if (!parent[levels[i]])
return undefined;
parent = parent[levels[i]];
}
return parent;
}
});
并更改了_dynamicSort的返回函数:
return function (a, b) {
var result = ((a.deepVal(property) > b.deepVal(property)) - (a.deepVal(property) < b.deepVal(property)));
return result * sortOrder;
}
现在你可以这样按a.a.排序:
obj.sortBy('a.a');
在JSFiddle中查看完整的脚本。
这将按照按字母数字顺序传递给它的属性对两级嵌套数组进行排序。
function sortArrayObjectsByPropAlphaNum(property) {
return function (a,b) {
var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
var aA = a[property].replace(reA, '');
var bA = b[property].replace(reA, '');
if(aA === bA) {
var aN = parseInt(a[property].replace(reN, ''), 10);
var bN = parseInt(b[property].replace(reN, ''), 10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
} else {
return a[property] > b[property] ? 1 : -1;
}
};
}
用法:
objs.sort(utils.sortArrayObjectsByPropAlphaNum('last_nom'));