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


当前回答

我会这样做:

[...objs].sort((a, b) => a.last_nom.localeCompare(b.last_nom))

其他回答

我一直在各种项目中使用这个实用程序,而且效果很好。它也非常模块化:

传递要排序的键的名称选择排序是升序还是降序

按KeyUtil.js排序对象数组

// Sort array of objects by key
// ------------------------------------------------------------
const sortArrayOfObjsByKey = (array, key, ascdesc) =>
  array.sort((a, b) => {
    const x = a[key];
    const y = b[key];
    if (ascdesc === 'asc') {
      return x < y ? -1 : x > y ? 1 : 0;
    }
    if (ascdesc === 'desc') {
      return x > y ? -1 : x < y ? 1 : 0;
    }
    return null;
  });

按KeyUtil.test.js排序对象数组

import sortArrayOfObjsByKey from './sortArrayOfObjsByKeyUtil';

const unsortedArray = [
  {
    _id: '3df55221-ce5c-4147-8e14-32effede6133',
    title: 'Netlife Design',
    address: {
      PostalAddress: {
        streetAddress: 'Youngstorget 3',
        addressLocality: 'Oslo',
        addressRegion: null,
        postalCode: '0181',
        addressCountry: 'Norway',
      },
    },
    geopoint: { lat: 59.914322, lng: 10.749272 },
  },
  {
    _id: 'cd00459f-3755-49f1-8847-66591ef935b2',
    title: 'Home',
    address: {
      PostalAddress: {
        streetAddress: 'Stockfleths gate 58A',
        addressLocality: 'Oslo',
        addressRegion: null,
        postalCode: '0461',
        addressCountry: 'Norway',
      },
    },
    geopoint: { lat: 59.937316, lng: 10.751862 },
  },
];

const sortedArray = [
  {
    _id: 'cd00459f-3755-49f1-8847-66591ef935b2',
    title: 'Home',
    address: {
      PostalAddress: {
        streetAddress: 'Stockfleths gate 58A',
        addressLocality: 'Oslo',
        addressRegion: null,
        postalCode: '0461',
        addressCountry: 'Norway',
      },
    },
    geopoint: { lat: 59.937316, lng: 10.751862 },
  },
  {
    _id: '3df55221-ce5c-4147-8e14-32effede6133',
    title: 'Netlife Design',
    address: {
      PostalAddress: {
        streetAddress: 'Youngstorget 3',
        addressLocality: 'Oslo',
        addressRegion: null,
        postalCode: '0181',
        addressCountry: 'Norway',
      },
    },
    geopoint: { lat: 59.914322, lng: 10.749272 },
  },
];

describe('sortArrayOfObjsByKey', () => {
  it(`sort array by 'title' key, ascending`, () => {
    const testInput = sortArrayOfObjsByKey(unsortedArray, 'title', 'asc');
    const testOutput = sortedArray;
    expect(testInput).toEqual(testOutput);
  });
});

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

我会这样做:

[...objs].sort((a, b) => a.last_nom.localeCompare(b.last_nom))

您也可以使用自定义toString()方法(由默认比较函数调用)创建对象类型,而不是使用自定义比较函数:

function Person(firstName, lastName) {
    this.firtName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.lastName + ', ' + this.firstName;
}

var persons = [ new Person('Lazslo', 'Jamf'), ...]
persons.sort();