我有一个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));

其他回答

一个简单的方法:

objs.sort(function(a,b) {
  return b.last_nom.toLowerCase() < a.last_nom.toLowerCase();
});

请注意,“.toLowerCase()”是防止错误所必需的在比较字符串时。

function compare(propName) {
    return function(a,b) {
        if (a[propName] < b[propName])
            return -1;
        if (a[propName] > b[propName])
            return 1;
        return 0;
    };
}

objs.sort(compare("last_nom"));

还有一个选项:

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

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

示例用法:

objs.sort(sortBy('last_nom'));

脚本:

/**
 * @description
 * Returns a function which will sort an
 * array of objects by the given key.
 *
 * @param  {String}  key
 * @param  {Boolean} reverse
 * @return {Function}
 */
const sortBy = (key, reverse) => {

  // Move smaller items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveSmaller = reverse ? 1 : -1;

  // Move larger items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveLarger = reverse ? -1 : 1;

  /**
   * @param  {*} a
   * @param  {*} b
   * @return {Number}
   */
  return (a, b) => {
    if (a[key] < b[key]) {
      return moveSmaller;
    }
    if (a[key] > b[key]) {
      return moveLarger;
    }
    return 0;
  };
};

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

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

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