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


当前回答

我还没有看到这种特别的方法,所以这里有一个我喜欢使用的简洁的比较方法,它适用于字符串和数字类型:

常量对象=[{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));

其他回答

对对象数组进行排序

// Data
var booksArray = [
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

// Property to sort by
var args = "last_nom";

// Function to sort the data by the given property
function sortByProperty(property) {
    return function (a, b) {
        var sortStatus = 0,
            aProp = a[property].toLowerCase(),
            bProp = b[property].toLowerCase();
        if (aProp < bProp) {
            sortStatus = -1;
        } else if (aProp > bProp) {
            sortStatus = 1;
        }
        return sortStatus;
    };
}

// Implementation
var sortedArray = booksArray.sort(sortByProperty(args));

console.log("sortedArray: " + JSON.stringify(sortedArray) );

控制台日志输出:

"sortedArray: 
[{"first_nom":"Pig","last_nom":"Bodine"},
{"first_nom":"Lazslo","last_nom":"Jamf"},
{"first_nom":"Pirate","last_nom":"Prentice"}]"

基于此来源改编:代码段:如何按属性对JSON对象数组排序

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

对于工作狂:

const objectSorter = (p) => (a, b) => ((a, b) => a>b ? 1 : a<b ? -1 : 0)(a[p], b[p]);
objs.sort(objectSorter('first_nom'));

所以这里有一种排序算法,它可以在任何类型的对象数组中按任何顺序排序,而不受数据类型比较的限制(如Number、String等):

function smoothSort(items,prop,reverse) {
    var length = items.length;
    for (var i = (length - 1); i >= 0; i--) {
        //Number of passes
        for (var j = (length - i); j > 0; j--) {
            //Compare the adjacent positions
            if(reverse){
              if (items[j][prop] > items[j - 1][prop]) {
                //Swap the numbers
                var tmp = items[j];
                items[j] = items[j - 1];
                items[j - 1] = tmp;
            }
            }

            if(!reverse){
              if (items[j][prop] < items[j - 1][prop]) {
                  //Swap the numbers
                  var tmp = items[j];
                  items[j] = items[j - 1];
                  items[j - 1] = tmp;
              }
            }
        }
    }

    return items;
}

第一参数项是对象数组,prop是要排序的对象的键,reverse是一个布尔参数,如果为true,则返回升序,如果为false,则返回降序。

如果您有嵌套对象

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