在JavaScript中按字符串属性值排序对象数组

我有一个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(function(a,b) {return (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"));

将它添加到原型

(下面的实现来自Mike R的答案)

我不建议更改本地对象原型,只是为了给出一个示例,以便您可以在自己的对象上实现它 (对于支持它的环境,还可以使用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。


underscore.js

使用下划线,其小而真棒...

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' );
链接地址: http://www.djcxy.com/p/421.html

上一篇: Sort array of objects by string property value in JavaScript

下一篇: How do you check if a variable is an array in JavaScript?