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


当前回答

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

其他回答

使用原型继承简单快速地解决此问题:

Array.prototype.sortBy = function(p) {
  return this.slice(0).sort(function(a,b) {
    return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
  });
}

示例/用法

objs = [{age:44,name:'vinay'},{age:24,name:'deepak'},{age:74,name:'suresh'}];

objs.sortBy('age');
// Returns
// [{"age":24,"name":"deepak"},{"age":44,"name":"vinay"},{"age":74,"name":"suresh"}]

objs.sortBy('name');
// Returns
// [{"age":24,"name":"deepak"},{"age":74,"name":"suresh"},{"age":44,"name":"vinay"}]

更新:不再修改原始数组。

我将给您一个实现选择排序算法的解决方案。它简单有效。

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


function selection_Sort(num) {
  //console.log(num);
  var temp, index;
  for (var i = 0; i <= num.length - 1; i++) {
    index = i;

    for (var j = i + 1; j <= num.length - 1; j++) {
      // You can use first_nom/last_nom, any way you choose to sort

      if (num[j].last_nom < num[index].last_nom) {
        index = j;
      }
    }

    // Below is the swapping part
    temp = num[i].last_nom;
    num[i].last_nom = num[index].last_nom;
    num[index].last_nom = temp;
  };
  console.log(num);
  return num;
}

selection_Sort(objs);

您可以使用可重用的排序函数。

Array.prototype.order = function (prop, methods = {}) {
    if (prop?.constructor == Object) {
        methods = prop;
        prop = null;
    }
    const [orderType_a, orderType_b] = methods.reverse ? [1, -1] : [-1, 1];

    const $ = x => prop
        ? methods.insensitive
            ? String(x[prop]).toLowerCase()
            : x[prop]
        : methods.insensitive
            ? String(x).toLowerCase()
            : x;

    const fn = (a, b) => $(a) < $(b) ? orderType_a : $(b) < $(a) ? orderType_b : 0;
    return this.sort(fn);
};

它可用于对数组和数组中的对象进行排序。

let items = [{ x: "Z" }, 3, "1", "0", 2, { x: "a" }, { x: 0 }];
items
    .order("x", { insensitive: 1 })
    // [ { x: 0 }, { x: 'a' }, 3, '1', '0', 2, { x: 'Z' } ]
    .order({ reverse: 1 })
    // [ { x: 0 }, { x: 'a' }, 3, 2, { x: 'Z' }, '1', '0' ]
    .sort(x => typeof x == "string" || typeof x == "number" ? -1 : 0)
    // [ '0', '1', 2, 3, { x: 0 }, { x: 'a' }, { x: 'Z' } ]

1nd(可选)>对数组中包含的对象进行排序。2rd是方法>{reverse:any,不敏感:any}

当您需要自然排序(即1,2,10,111111)时,使用Intl.Collator对特定情况的对象进行排序。

常量文件=[{name:“1.mp3”,大小:123},{name:“10.mp3”,大小:456},{name:“100.mp3”,大小:789},{name:“11.mp3”,大小:123},{name:“111.mp3”,大小:456},{name:“2.mp3”,大小:789},];const naturalCollator=新Intl.Collator(未定义,{numeric:true,sensitity:'base'});files.sort((a,b)=>naturalCollator.compare(a.name,b.name));console.log(文件);

浏览器支持Intl.Collator

将Ege的动态解决方案与Vinay的想法相结合,您可以得到一个很好的鲁棒解决方案:

Array.prototype.sortBy=函数(){函数_sortByAttr(属性){var sortOrder=1;如果(属性[0]==“-”){sortOrder=-1;attr=attr.substr(1);}返回函数(a,b){var结果=(a[attr]<b[attr])-1:(a[attr]>b[attr])?1 : 0;返回结果*sortOrder;}}函数_getSortFunc(){if(arguments.length==0){throw“Array.sortBy()不允许零长度参数”;}var args=参数;返回函数(a,b){for(var result=0,i=0;result==0&&i<args.length;i++){result=_sortByAttr(args[i])(a,b);}返回结果;}}返回this.sort(_getSortFunc.apply(null,arguments));}用法://用于打印对象的实用程序Array.prototype.print=函数(标题){console.log(“************************************************************”);console.log(“***”+标题);console.log(“************************************************************”);对于(var i=0;i<this.length;i++){console.log(“名称:”+此[i].FirstName,此[i].LastName,“年龄:”+该[i].Age);}}//设置示例数据变量arrObj=[{名字:“Zach”,姓氏:“Emergency”,年龄:35岁},{名字:“Nancy”,姓氏:“护士”,年龄:27岁},{名字:“Ethel”,姓氏:“Emergency”,年龄:42岁},{名字:“Nina”,姓氏:“护士”,年龄:48岁},{名字:“Anthony”,姓氏:“Emergency”,年龄:44岁},{名字:“Nina”,姓氏:“护士”,年龄:32岁},{名字:“Ed”,姓氏:“Emergency”,年龄:28岁},{名字:“Peter”,姓氏:“医生”,年龄:58岁},{名字:“Al”,姓氏:“Emergency”,年龄:51岁},{名字:“Ruth”,姓氏:“注册”,年龄:62岁},{名字:“Ed”,姓氏:“Emergency”,年龄:38岁},{名字:“Tammy”,姓氏:“Triage”,年龄:29岁},{名字:“Alan”,姓氏:“Emergency”,年龄:60岁},{名字:“Nina”,姓氏:“护士”,年龄:54岁}];//单元测试arrObj.sortBy(“姓氏”).print(“姓氏升序”);arrObj.sortBy(“-姓氏”).print(“姓氏降序”);arrObj.sortBy(“姓氏”、“名字”、“年龄”).print(“姓氏升序、名字升序、年龄降序”);arrObj.sortBy(“-FirstName”,“Age”).print(“FirstName降序,Age升序”);arrObj.sortBy(“-Age”).print(“Age Descending”);