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


当前回答

我遇到了排序对象数组的问题,改变了值的优先级。基本上,我想按年龄,然后按姓氏,或者仅仅按姓氏,名字来对一系列人进行排序。

我认为与其他答案相比,这是最简单的解决方案。

它用于调用sortPeoples(['array','of','properties'],reverse=false)。

///////////////////////人群示例阵列///////////////////////var人民=[{姓名:“Zach”,姓:“Emergency”,年龄:1},{姓名:“南希”,姓:“护士”,年龄:1岁},{姓名:“Ethel”,姓:“Emergency”,年龄:1},{姓名:“尼娜”,姓:“护士”,年龄:42岁},{姓名:“Anthony”,姓:“Emergency”,年龄:42岁},{姓名:“尼娜”,姓:“护士”,年龄:32岁},{姓名:“Ed”,姓:“Emergency”,年龄:28岁},{姓名:“彼得”,姓:“医生”,年龄:58岁},{姓名:“Al”,姓:“Emergency”,年龄:58岁},{姓名:“Ruth”,姓:“Registration”,年龄:62岁},{姓名:“Ed”,姓:“Emergency”,年龄:38岁},{姓名:“Tammy”,姓:“Triage”,年龄:29岁},{姓名:“Alan”,姓:“Emergency”,年龄:60岁},{姓名:“尼娜”,姓:“护士”,年龄:58岁}];////////////////////////排序功能/////////////////////函数sortPeoples(propertyArr,reverse){函数比较(a,b){变量i=0;while(propertyArr[i]){如果(a[propertyArr[i]]<b[propertyAr[i]])返回-1;如果(a[propertyArr[i]]>b[propertyAr[i]])返回1;i++;}返回0;}人民。排序(比较);if(反向){peoples.reverse();}};////////////////排序方法结束///////////////函数printPeoples(){$(“#输出”).html(“”);people.forEach(功能(人){$('#output').append(person.surname+“”+person.name+““”+person.age+“<br>”);})}<head><script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script></head><html><body><button onclick=“sortPeoples(['surname']);printPeoples()”>仅按姓氏ASC排序会导致同名案例的混乱</button><br><button onclick=“sortPeoples(['surname','name],true);printPeoples()”>按姓氏排序,然后按名称DESC</button><br><button onclick=“sortPeoples(['age']);printPeoples()”>按age ASC排序。与第一种情况相同的问题</button><br><button onclick=“sortPeoples(['age','姓']);printPeoples()”>按age和姓氏ASC排序。添加第二个字段修复了它。</button><br><div id=“output”></div></body></html>

其他回答

这里有一个函数,您可以使用它按多个对象对列表进行排序,如果第一个对象相等,则第二个顺序将用作回退。如果可能的话,空值也应忽略到回退顺序。

function sortObjects(list, orderBy){
    list.sort(function(a, b){
        let byIndex = 0;
        let order = orderBy[byIndex];
        while(!a[order.by] || !b[order.by] || a[order.by] === b[order.by]){
            byIndex++;
            if(byIndex >= orderBy.length){break;}
            order = orderBy[byIndex];
        }
        if(!a[order.by] || !b[order.by] || a[order.by] === b[order.by]){
            return false;
        }
        if(order.desc){
            return a[order.by] < b[order.by];
        }
        return a[order.by] > b[order.by];
    });
    return list;
}

用法:

var objs = [
    {a: 10, b: 20, c: 30},
    {a: 30, b: 10, c: 20},
    {a: 20, b: 10, c: 30},
];

sortObjectList(objs, [{by: 'a'}]);
[
    {a: 10, b: 20, c: 30},
    {a: 20, b: 10, c: 30},
    {a: 30, b: 10, c: 20},
]

sortObjectList(objs, [{by: 'a', desc: true}]);
[
    {a: 30, b: 10, c: 20},
    {a: 20, b: 10, c: 30},
    {a: 10, b: 20, c: 30},
]

sortObjectList(objs, [{by: 'b', desc: true}, {by: 'c'}]);
[
    {a: 10, b: 20, c: 30},
    {a: 30, b: 10, c: 20},
    {a: 20, b: 10, c: 30},
]

另一个例子:

var objs = [
    {a: 5, b: 5},
    {a: 10, b: 15},
    {a: 15, b: 25},
    {b: 10},
    {b: 20},
    {a: 10, b: 30},
    {a: 10, b: 12},
];

sortObjectList(objs, [{by: 'a'}, {by: 'b'}]);
[
    {a: 5, b: 5},
    {b: 10},
    {a: 10, b: 12},
    {a: 10, b: 15},
    {b: 20},
    {a: 10, b: 30},
    {a: 15, b: 25},
]

示例用法:

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

Lodash(Undercore.js的超集)。

不为每一个简单的逻辑添加一个框架是很好的,但是依赖于经过良好测试的实用程序框架可以加快开发并减少错误数量。

Lodash生成了非常干净的代码,并促进了更具功能性的编程风格。一眼望去,代码的意图就一目了然了。

OP的问题可以简单地解决为:

const sortedObjs = _.sortBy(objs, 'last_nom');

更多信息?例如,我们有以下嵌套对象:

const users = [
  { 'user': {'name':'fred', 'age': 48}},
  { 'user': {'name':'barney', 'age': 36 }},
  { 'user': {'name':'wilma'}},
  { 'user': {'name':'betty', 'age': 32}}
];

我们现在可以使用_.properties速记user.age来指定应该匹配的属性的路径。我们将根据嵌套的年龄属性对用户对象进行排序。是的,它允许嵌套属性匹配!

const sortedObjs = _.sortBy(users, ['user.age']);

想要反转吗?没问题。使用_反向。

const sortedObjs = _.reverse(_.sortBy(users, ['user.age']));

想用链条将两者结合起来吗?

const { chain } = require('lodash');
const sortedObjs = chain(users).sortBy('user.age').reverse().value();

或者你什么时候更喜欢流动而不是链条?

const { flow, reverse, sortBy } = require('lodash/fp');
const sortedObjs = flow([sortBy('user.age'), reverse])(users);

您可以使用最简单的方式:Lodash

(https://lodash.com/docs/4.17.10#orderBy)

此方法类似于_.sortBy,只是它允许指定要排序的迭代项的排序顺序。如果未指定顺序,则所有值都按升序排序。否则,为相应值的降序指定“desc”,为升序指定“asc”。

论据

collection(Array | Object):要迭代的集合。[iteratees=[_.identity]](数组[]|函数[]|对象[]|字符串[]):要排序的iterates。[orders](string[]):迭代的排序顺序。

退换商品

(Array):返回新的排序数组。


var _ = require('lodash');
var homes = [
    {"h_id":"3",
     "city":"Dallas",
     "state":"TX",
     "zip":"75201",
     "price":"162500"},
    {"h_id":"4",
     "city":"Bevery Hills",
     "state":"CA",
     "zip":"90210",
     "price":"319250"},
    {"h_id":"6",
     "city":"Dallas",
     "state":"TX",
     "zip":"75000",
     "price":"556699"},
    {"h_id":"5",
     "city":"New York",
     "state":"NY",
     "zip":"00010",
     "price":"962500"}
    ];
    
_.orderBy(homes, ['city', 'state', 'zip'], ['asc', 'desc', 'asc']);

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

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

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