我有一个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()方法?
我刚刚增强了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中查看完整的脚本。
给定原始示例:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
按多个字段排序:
objs.sort(function(left, right) {
var last_nom_order = left.last_nom.localeCompare(right.last_nom);
var first_nom_order = left.first_nom.localeCompare(right.first_nom);
return last_nom_order || first_nom_order;
});
笔记
a.localeCompare(b)是普遍支持的,如果a<b,a==b,a>b,则分别返回-1,0,1。||在最后一行中,last_nom优先于first_nom。减法适用于数字字段:var age_order=left.age-right.age;取反顺序,返回-last_nom_order | |-first_nom_oorder | |-age_order;
我还没有看到这种特别的方法,所以这里有一个我喜欢使用的简洁的比较方法,它适用于字符串和数字类型:
常量对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'}];常量排序依据=fn=>{常量cmp=(a,b)=>-(a<b)||+(a>b);return(a,b)=>cmp(fn(a),fn(b));};const getLastName=o=>o.last_nom;const sortByLastName=sortBy(getLastName);objs.sort(sortByLastName);console.log(objs.map(getLastName));
sortBy()的解释
sortBy()接受一个fn,该fn从一个对象中选择一个值用于比较,并返回一个可以传递给Array.prototype.sort()的函数。在本例中,我们正在比较o.last_nom。每当我们收到两个对象,例如
a = { first_nom: 'Lazslo', last_nom: 'Jamf' }
b = { first_nom: 'Pig', last_nom: 'Bodine' }
我们将它们与(a,b)=>cmp(fn(a),fn(b))进行比较。鉴于此
fn = o => o.last_nom
我们可以将比较函数扩展为(a,b)=>cmp(a.last_nom,b.last_nom)。由于逻辑OR(||)在JavaScript中的工作方式,cmp(a.last_nom、b.last_nom)相当于
if (a.last_nom < b.last_nom) return -1;
if (a.last_nom > b.last_nom) return 1;
return 0;
顺便说一下,这在其他语言中被称为三向比较“宇宙飞船”(<=>)运算符。
最后,这里是不使用箭头函数的ES5兼容语法:
var对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'}];函数sortBy(fn){函数cmp(a,b){return-(a<b)| |+(a>b);}返回函数(a,b){return cmp(fn(a),fn(b));};}函数getLastName(o){return o.last_nom;}var sortByLastName=sortBy(getLastName);objs.sort(sortByLastName);console.log(objs.map(getLastName));