我有一个 JavaScript 对象数组:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
如何根据 JavaScript 中last_nom
的值对它们进行排序?
我知道sort(a,b)
,但这似乎只适用于字符串和数字。我是否需要在对象中添加toString()
方法?
编写自己的比较函数很容易:
function compare(a,b) {
if (a.last_nom < b.last_nom)
return -1;
if (a.last_nom > b.last_nom)
return 1;
return 0;
}
objs.sort(compare);
或内联(c / o Marco Demaio):
objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0));
您还可以创建一个动态排序函数,按照您传递的值对对象进行排序:
function dynamicSort(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a,b) {
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
所以你可以有一个这样的对象数组:
var People = [
{Name: "Name", Surname: "Surname"},
{Name:"AAA", Surname:"ZZZ"},
{Name: "Name", Surname: "AAA"}
];
...... 当你这样做时它会起作用:
People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));
实际上这已经回答了这个问题。下面的部分是因为许多人联系我,抱怨它不适用于多个参数 。
您可以使用以下函数生成具有多个排序参数的排序函数。
function dynamicSortMultiple() {
/*
* save the arguments object as it will be overwritten
* note that arguments object is an array-like object
* consisting of the names of the properties to sort by
*/
var props = arguments;
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length;
/* try getting a different result from 0 (equal)
* as long as we have extra properties to compare
*/
while(result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
}
}
这将使您能够做到这样的事情:
People.sort(dynamicSortMultiple("Name", "-Surname"));
我不建议更改本机对象原型,只是为了给出一个示例,以便您可以在自己的对象上实现它 (对于支持它的环境,您也可以使用Object.defineProperty ,如下一节所示,至少没有可枚举的负面副作用,如最后一部分所述)
原型实现将类似于以下( 这是一个工作示例 ):
//Don't just copy-paste this code. You will break the "for-in" loops
!function() {
function _dynamicSortMultiple(attr) {
/* dynamicSortMultiple function body comes here */
}
function _dynamicSort(property) {
/* dynamicSort function body comes here */
}
Array.prototype.sortBy = function() {
return this.sort(_dynamicSortMultiple.apply(null, arguments));
}
}();
如果你的目标是 IE v9.0,那么就像我之前提到的那样,使用像这样的Object.defineProperty ( 工作示例 ):
//Won't work below IE9, but totally safe otherwise
!function() {
function _dynamicSortMultiple(attr) {
/* dynamicSortMultiple function body comes here */
}
function _dynamicSort(property) {
/* dynamicSort function body comes here */
}
Object.defineProperty(Array.prototype, "sortBy", {
enumerable: false,
writable: true,
value: function() {
return this.sort(_dynamicSortMultiple.apply(null, arguments));
}
});
}();
在绑定运算符到达之前,这可以是可接受的折衷方案。
所有这些原型乐趣都可以实现:
People.sortBy("Name", "-Surname");
如果你使用直接原型访问方法(Object.defineProperty 很好)而其他代码没有检查hasOwnProperty ,小猫会死!好吧,说实话,任何小猫都没有受到伤害,但可能事情会破裂,团队中的其他开发人员都会讨厌你:
看到最后一个 “SortBy”?是啊。不酷。尽可能使用 Object.defineProperty,否则单独保留 Array.prototype。
使用下划线,它小而且棒极了......
sortBy_.sortBy(list,iterator,[context])返回列表的排序副本,按照通过迭代器运行每个值的结果按升序排列。迭代器也可以是要排序的属性的字符串名称(例如,长度)。
var objs = [
{ first_nom: 'Lazslo',last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
var sortedObjs = _.sortBy( objs, 'first_nom' );