我有一个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()方法?


当前回答

此排序功能可用于所有对象排序:

对象deepObject(深度对象)数字数组

您还可以通过传递1,-1作为参数进行升序或降序排序。

Object.defineProperty(Object.prototype,'deepVal'{可枚举:false,可写:true,值:函数(propertyChain){var level=propertyChain.split('.');父项=此项;对于(var i=0;i<levels.length;i++){if(!parent[levels[i]])返回未定义;parent=父[级别[i]];}返回父项;}});函数dynamicSortAll(属性,sortOrders=1){/**默认排序为升序。如果你需要按降序排序传递-1作为参数**/var sortOrder=sortOrders;返回函数(a,b){var result=(属性?((a.deepVal(属性)>b.deepVal(属性))?1:(a.deepVal(属性)<b.deepVal(属性))-1:0):((a>b)?1:(a<b)-1 : 0))返回结果*sortOrder;}}深度对象=[{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}}];let deepobjResult=deepObj.sort(dynamicSortAll('a.a',1))console.log('deepobjResult:'+JSON.stringify(deepojResult))变量obj=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'}];let objResult=obj.sort(dynamicSortAll('last_nom',1))console.log('objResult:'+JSON.stringify(objResult))var numericObj=[1,2,3,4,5,6]let numResult=numericObj.sort(dynamicSortAll(null,-1))console.log('numResult:'+JSON.stringify(numResult))let stringSortResult='helloworld'.split('').sort(dynamicSortAll(null,1))console.log('stringSortResult:'+JSON.stringify(stringSortResult))let uniqueStringOrger=[…new Set(stringSortResult)];console.log('uniqueStringOrger:'+JSON.stringify(uniqueStringOrger))

其他回答

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

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

Deep

基于这篇优秀的教程,我想开发Vlad Bezden的答案,并解释为什么localeCompare优于标准比较方法,如strA>strB。让我们运行以下示例:

console.log(“Österreich”>“Zealand”);//我们期望错误console.log(“a”>“Z”);//我们期望错误

原因是在JavaScript中,所有字符串都使用UTF-16编码

让str=“”;//JavaScript中的字符顺序for(设i=65;i<=220;i++){str+=字符串.fromCodePoint(i);//代码到字符}console.log(str);

首先是大写字母(有小代码),然后是小写字母,然后是字符Ö(在z之后)。这就是为什么我们在第一个代码段中得到正确的原因,因为运算符>比较字符代码。

如您所见,比较不同语言中的字符是一项非常重要的任务,但幸运的是,现代浏览器支持国际化标准ECMA-402。所以在JavaScript中,我们有strA.localeCompare(strB)来完成任务(-1表示strA小于strB;1表示相反;0表示相等)

console.log('Österreich'.localeCompare('Zealand'));//我们期望-1console.log('a'.localeCompare('Z'));//我们期望-1

我想补充一点,localeCompare支持两个参数:语言和其他规则:

var对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'},{first_nom:'测试',last_nom:'jamf'}];objs.sort((a,b)=>a.last_nom.localeCompare(b.last_nom,'en',{sensitity:'case'}))console.log(objs);//在'>'比较中,'Jamf'不会在'Jamf'旁边

还有一个选项:

var someArray = [...];

function generateSortFn(prop, reverse) {
    return function (a, b) {
        if (a[prop] < b[prop]) return reverse ? 1 : -1;
        if (a[prop] > b[prop]) return reverse ? -1 : 1;
        return 0;
    };
}

someArray.sort(generateSortFn('name', true));

默认情况下,它按升序排序。

这是一个简单的问题。我不知道为什么人们会有如此复杂的解决方案。

一个简单的排序函数(基于快速排序算法):

function sortObjectsArray(objectsArray, sortKey)
{
    // Quick Sort:
    var retVal;

    if (1 < objectsArray.length)
    {
        var pivotIndex = Math.floor((objectsArray.length - 1) / 2);  // Middle index
        var pivotItem = objectsArray[pivotIndex];                    // Value in the middle index
        var less = [], more = [];

        objectsArray.splice(pivotIndex, 1);                          // Remove the item in the pivot position
        objectsArray.forEach(function(value, index, array)
        {
            value[sortKey] <= pivotItem[sortKey] ?                   // Compare the 'sortKey' proiperty
                less.push(value) :
                more.push(value) ;
        });

        retVal = sortObjectsArray(less, sortKey).concat([pivotItem], sortObjectsArray(more, sortKey));
    }
    else
    {
        retVal = objectsArray;
    }

    return retVal;
}

使用示例:

var myArr =
        [
            { val: 'x', idx: 3 },
            { val: 'y', idx: 2 },
            { val: 'z', idx: 5 },
        ];

myArr = sortObjectsArray(myArr, 'idx');

如果您有嵌套对象

const objs = [{
        first_nom: 'Lazslo',
        last_nom: 'Jamf',
        moreDetails: {
            age: 20
        }
    }, {
        first_nom: 'Pig',
        last_nom: 'Bodine',
        moreDetails: {
            age: 21
        }
    }, {
        first_nom: 'Pirate',
        last_nom: 'Prentice',
        moreDetails: {
            age: 22
        }
    }];

nestedSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {
        const a = prop2 ? e1[prop1][prop2] : e1[prop1],
            b = prop2 ? e2[prop1][prop2] : e2[prop1],
            sortOrder = direction === "asc" ? 1 : -1
        return (a < b) ? -sortOrder : (a > b) ? sortOrder : 0;
    }

并称之为

objs.sort(nestedSort("last_nom"));
objs.sort(nestedSort("last_nom", null, "desc"));
objs.sort(nestedSort("moreDetails", "age"));
objs.sort(nestedSort("moreDetails", "age", "desc"));