8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

按字符串属性值对对象数组进行排序

CodeByAk 1月前

45 0

我有一个 JavaScript 对象数组:var objs = [ { first_nom: 'Laszlo', last_nom: 'Jamf' }, { first_nom: 'Pig', last_nom: 'Bodine' }, { first_nom: 'Pirate', last_nom: 'Pren...

我有一个 JavaScript 对象数组:

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

我如何根据 JavaScript 中的值对它们进行排序 last_nom

我知道 sort(a,b) ,但这似乎只适用于字符串和数字。我需要 toString() 向对象添加方法吗?

帖子版权声明 1、本帖标题:按字符串属性值对对象数组进行排序
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由CodeByAk在本站《sorting》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 编写自己的比较函数非常简单:

    function compare( a, b ) {
      if ( a.last_nom < b.last_nom ){
        return -1;
      }
      if ( a.last_nom > b.last_nom ){
        return 1;
      }
      return 0;
    }
    
    objs.sort( compare );
    

    或内联( c/o Marco Demaio ):

    objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0))
    

    或者简化为数字( c/o Andre Figueiredo ):

    objs.sort((a,b) => a.last_nom - b.last_nom); // b - a for reverse sort
    
  • 或者内联:objs.sort(function(a,b) {return (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0);});

  • 官方文档:developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…

  • 返回 a.last_nom.localeCompare(b.last_nom) 也将起作用。

  • 对于那些寻找字段为数字的排序的人来说,比较函数体:返回 a.value - b.value;(ASC)

  • ack 1月前 0 只看Ta
    引用 7

    您可以使用 charCodeAt 将字符串转换为数字,然后使用上面的数字内联获得更简洁的一行:objs.sort((a,b) => a.last_nom.charCodeAt(0) - b.last_nom.charCodeAt(0));。这避免了丑陋的嵌套三元组。

  • 您还可以创建一个动态排序函数,根据您传递的值对对象进行排序:

    function dynamicSort(property) {
        var sortOrder = 1;
        if(property[0] === "-") {
            sortOrder = -1;
            property = property.substr(1);
        }
        return function (a,b) {
            /* next line works with strings and numbers, 
             * and you may want to customize it to your needs
             */
            var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
            return result * sortOrder;
        }
    }
    

    因此你可以拥有如下对象数组:

    var People = [
        {Name: "Name", Surname: "Surname"},
        {Name:"AAA", Surname:"ZZZ"},
        {Name: "Name", Surname: "AAA"}
    ];
    

    ...当你这样做时它就会起作用:

    People.sort(dynamicSort("Name"));
    People.sort(dynamicSort("Surname"));
    People.sort(dynamicSort("-Surname"));
    

    其实这已经回答了这个问题。下面部分是因为很多人联系我,抱怨它 不适用于多个参数 .

    多个参数

    您可以使用下面的函数来生成具有多个排序参数的排序函数。

    function dynamicSortMultiple() {
        /*
         * save the arguments object as it will be overwritten
         * note that arguments object is an array-like object
         * consisting of the names of the properties to sort by
         */
        var props = arguments;
        return function (obj1, obj2) {
            var i = 0, result = 0, numberOfProperties = props.length;
            /* try getting a different result from 0 (equal)
             * as long as we have extra properties to compare
             */
            while(result === 0 && i < numberOfProperties) {
                result = dynamicSort(props[i])(obj1, obj2);
                i++;
            }
            return result;
        }
    }
    

    这将使你能够做这样的事情:

    People.sort(dynamicSortMultiple("Name", "-Surname"));
    

    子类化数组

    对于我们这些幸运的人来说,可以使用 ES6,它允许扩展本机对象:

    class MyArray extends Array {
        sortBy(...args) {
            return this.sort(dynamicSortMultiple(...args));
        }
    }
    

    这将实现这一点:

    MyArray.from(People).sortBy("Name", "-Surname");
    
  • 很好。现在有这个答案的 Typescript 版本:.com/a/68279093/8910547。保持(打字)安全!

  • @zero_cool 数组在这里没有被扩展(原型保持不变),而是从中扩展而来。你确实不应该改变原生对象的原型,但正如我所说,这里的情况并非如此。

  • @serge 任何字符串和空值的比较都将导致错误,并将空值放在最后。如果将 a[property] < b[property] 更改为 a[property].localeCompare(b[property]),则可以执行 a[property]?.localeCompare(b[property]) ?? 1(如果 a 的属性为空,则首先将 b 作为首选,如果 b 的属性为空,localeCompare 无论如何都会返回 -1——但当两者都为空时不合逻辑,因此也许也要检查一下这一点)

  • ES6/ES2015 或更高版本中,你可以这样做:

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

    ES6/ES2015 之前

    objs.sort(function(a, b) {
        return a.last_nom.localeCompare(b.last_nom)
    });
    
  • 如果值是数字,则不需要 localeCompare。您可以使用标准 > 运算符 - 就像 @muasif80 在回答中提到的那样 - .com/a/67992215/6908282

  • 14.5 英寸 x 20 英寸与 14 英寸 x 4370 英尺不符。我可以使用其他逻辑吗?

  • 引用 15

    Underscore.js

    使用 Underscore.js。它很小而且很棒……

    sortBy_.sortBy(list, iterator, [context]) 返回列表的排序副本,按通过迭代器运行每个值的结果按升序排列。迭代器也可以是要排序的属性的字符串名称(例如长度)。

    var objs = [
      { first_nom: 'Lazslo',last_nom: 'Jamf' },
      { first_nom: 'Pig', last_nom: 'Bodine'  },
      { first_nom: 'Pirate', last_nom: 'Prentice' }
    ];
    
    var sortedObjs = _.sortBy(objs, 'first_nom');
    
  • David,您能否将答案修改为 var sortedObjs = _.sortBy( objs, 'first_nom' );。这样 objs 本身将不会被排序。该函数将返回一个已排序的数组。这样会更明确。

  • 反向排序: varverseSortedObjs = _.sortBy( objs, 'first_nom' ).reverse();

  • 在 lodash 中这将是相同的:var sortedObjs = _.sortBy( objs, 'first_nom' ); 或者如果你想要以不同的顺序:var sortedObjs = _.orderBy( objs, ['first_nom'],['dsc'] );

  • 区分大小写

    arr.sort((a, b) => a.name > b.name ? 1 : -1);
    

    不区分大小写

    arr.sort((a, b) => a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1);
    

    有用的提示

    如果顺序没有变化(如果字符串相同),则条件 > 将失败并 -1 返回。但如果字符串相同,则返回 1 或 -1 将导致正确输出

    另一种选择是使用 >= 运算符代替 >


    var objs = [ 
        { first_nom: 'Lazslo', last_nom: 'Jamf'     },
        { first_nom: 'Pig',    last_nom: 'Bodine'   },
        { first_nom: 'Pirate', last_nom: 'Prentice' }
    ];
    
    
    // Define a couple of sorting callback functions, one with hardcoded sort key and the other with an argument sort key
    const sorter1 = (a, b) => a.last_nom.toLowerCase() > b.last_nom.toLowerCase() ? 1 : -1;
    const sorter2 = (sortBy) => (a, b) => a[sortBy].toLowerCase() > b[sortBy].toLowerCase() ? 1 : -1;
    
    objs.sort(sorter1);
    console.log("Using sorter1 - Hardcoded sort property last_name", objs);
    
    objs.sort(sorter2('first_nom'));
    console.log("Using sorter2 - passed param sortBy='first_nom'", objs);
    
    objs.sort(sorter2('last_nom'));
    console.log("Using sorter2 - passed param sortBy='last_nom'", objs);
  • 提示:如果你想反转顺序,你可以简单地交换 -1 和 1,例如:从 1:-1 到 -1:1

返回
作者最近主题: