关于javascript:按字符串属性值对对象数组排序

 2019-04-22 

Sort array of objects by string property value

我有一个javascript对象数组:

1
2
3
4
5
var objs = [
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

如何按javascript中last_nom的值对它们进行排序?

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


编写自己的比较函数很容易:

1
2
3
4
5
6
7
8
9
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):

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


还可以创建一个动态排序函数,该函数按传递的值对对象进行排序:

1
2
3
4
5
6
7
8
9
10
11
function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] ==="-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

所以您可以有这样的对象数组:

1
2
3
var People = [
    {Name:"Name", Surname:"Surname
<div class="
suo-content">[collapse title=""]<ul><li>请注意,javascript中的属性名称可以是任何字符串,如果属性以"-"开头(极不可能,也可能不是一个好主意),则需要修改dynamicsort函数以使用其他内容作为反向排序指示器。</li><li>我注意到上面例子中的<wyn>dynamicSort()</wyn>将把大写字母放在小写字母之前。例如,如果我有值<wyn>APd</wyn>、<wyn>Aklin</wyn>和<wyn>Abe</wyn>,那么asc排序的结果应该是<wyn>Abe</wyn>、<wyn>Aklin</wyn>、<wyn>APd</wyn>。但以你的例子来说,结果是<wyn>APd</wyn>、<wyn>Abe</wyn>、<wyn>Aklin</wyn>。要纠正这种行为吗?</li><li>@劳埃德银行如果您严格地使用这个字符串,那么您可以使用<wyn>var result = a[property].localeCompare(b[property]);</wyn>,而不是<wyn>var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;</wyn>。</li><li>就像最重要的答案一样,如果存在不完善的属性,这个答案也会失败:<wyn>[ { a: 5 }, {a:2}, {}, {a:1} ]</wyn>。</li><li>@dzh-um,未定义的键应该如何处理?你可以做些不同的事情来实现这一目标。1)获取一个默认值,并将其与<wyn>a[property] || defaultVal</wyn>进行比较。2)如果[属性]为空,则始终返回-1(或1)。这是一个图灵完整的语言,你不可能处理所有的情况。当A是一个投球手时会发生什么?可能有无限数量的案例。</li><li>@ege&214;zcan它应该要么把项目放在顶部,要么放在底部,下面是我使用pastebin.com/g4dt23ju完成的实现。</li><li>@你也可以在上面添加相同的转义符(’’),它的作用也一样。在排序对象时,没有一种适合所有对象的解决方案。</li><li>这是一个很好的解决方案,但如果你比较数字,就有一个问题。请在支票前加上:<wyn>if( !isNaN(a[property]) ) a[property] = Number(a[property]); if( !isNaN(b[property]) ) b[property] = Number(b[property]);</wyn>。</li><li>这太棒了!如果只使用一个util类,那么所有的<wyn>hasOwnProperty</wyn>问题都可以避免。<wyn>Util.sortBy( People,"Name","-Surname" )</wyn>等</li></ul>[/collapse]</div><hr><P>在ES6/ES2015或更高版本中,您可以这样做:</P>[cc lang="javascript"]objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));


underscore.js

use underscore, its small and awesome...

sortBy_.sortBy(list, iterator, [context]) Returns a sorted copy of
list, ranked in ascending order by the results of running each value
through iterator. Iterator may also be the string name of the property
to sort by (eg. length).

1
2
3
4
5
6
7
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' );