我有一个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代码的其他描述参数:

function dynamicSort(property, desc) {
    if (desc) {
        return function (a, b) {
            return (a[property] > b[property]) ? -1 : (a[property] < b[property]) ? 1 : 0;
        }
    }
    return function (a, b) {
        return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
    }
}

其他回答

我刚刚增强了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中查看完整的脚本。

在TypeScript中编程时,也可以创建动态排序函数,但在这种情况下,类型变得更加复杂。

function sortByKey<O>(key: keyof O, decending: boolean = false): (a: O, b: O) => number {
    const order = decending ? -1 : 1;
    return (a, b): number => {
        const valA = a[key];
        const valB = b[key];
        if (valA < valB) {
            return -order;
        } else if (valA > valB) {
            return order;
        } else {
            return 0;
        }
    }
}

这可以在TypeScript中使用,如下所示:

const test = [
    {
        id: 0,
    },
    {
        id: 2,
    }
]

test.sort(sortByKey('id')) // OK
test.sort(sortByKey('id1')) // ERROR
test.sort(sortByKey('')) // ERROR

编写自己的比较函数非常简单:

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 );

或内联(由Marco Demaio转交):

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0))

或简化为数字(由Andre Figueiredo转交):

objs.sort((a,b) => a.last_nom - b.last_nom); // b - a for reverse sort

将Ege的动态解决方案与Vinay的想法相结合,您可以得到一个很好的鲁棒解决方案:

Array.prototype.sortBy=函数(){函数_sortByAttr(属性){var sortOrder=1;如果(属性[0]==“-”){sortOrder=-1;attr=attr.substr(1);}返回函数(a,b){var结果=(a[attr]<b[attr])-1:(a[attr]>b[attr])?1 : 0;返回结果*sortOrder;}}函数_getSortFunc(){if(arguments.length==0){throw“Array.sortBy()不允许零长度参数”;}var args=参数;返回函数(a,b){for(var result=0,i=0;result==0&&i<args.length;i++){result=_sortByAttr(args[i])(a,b);}返回结果;}}返回this.sort(_getSortFunc.apply(null,arguments));}用法://用于打印对象的实用程序Array.prototype.print=函数(标题){console.log(“************************************************************”);console.log(“***”+标题);console.log(“************************************************************”);对于(var i=0;i<this.length;i++){console.log(“名称:”+此[i].FirstName,此[i].LastName,“年龄:”+该[i].Age);}}//设置示例数据变量arrObj=[{名字:“Zach”,姓氏:“Emergency”,年龄:35岁},{名字:“Nancy”,姓氏:“护士”,年龄:27岁},{名字:“Ethel”,姓氏:“Emergency”,年龄:42岁},{名字:“Nina”,姓氏:“护士”,年龄:48岁},{名字:“Anthony”,姓氏:“Emergency”,年龄:44岁},{名字:“Nina”,姓氏:“护士”,年龄:32岁},{名字:“Ed”,姓氏:“Emergency”,年龄:28岁},{名字:“Peter”,姓氏:“医生”,年龄:58岁},{名字:“Al”,姓氏:“Emergency”,年龄:51岁},{名字:“Ruth”,姓氏:“注册”,年龄:62岁},{名字:“Ed”,姓氏:“Emergency”,年龄:38岁},{名字:“Tammy”,姓氏:“Triage”,年龄:29岁},{名字:“Alan”,姓氏:“Emergency”,年龄:60岁},{名字:“Nina”,姓氏:“护士”,年龄:54岁}];//单元测试arrObj.sortBy(“姓氏”).print(“姓氏升序”);arrObj.sortBy(“-姓氏”).print(“姓氏降序”);arrObj.sortBy(“姓氏”、“名字”、“年龄”).print(“姓氏升序、名字升序、年龄降序”);arrObj.sortBy(“-FirstName”,“Age”).print(“FirstName降序,Age升序”);arrObj.sortBy(“-Age”).print(“Age Descending”);

这将按照按字母数字顺序传递给它的属性对两级嵌套数组进行排序。

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'));