js对象排序有几种方法(js中对象数组排序的方法)

如果需要按特定顺序对对象数组进行排序,我们很有可能会直接找个 JS 库来用。其实大可不必,JS 原生中的 Array.sort就能直接一些复杂又漂亮的排序。

js对象排序有几种方法(js中对象数组排序的方法)

本文中,将介绍一些 Array.sort 的常规排序和一些骚操作。

基本数组排序

默认情况下,Array.sort函数将数组中需要排序的每个元素转换为字符串,并按 Unicode 顺序对其进行比较。

constfoo=[9,1,4,’zebroid’,’afterdeck’];foo.sort();//returns[1,4,9,’afterdeck’,’zebroid’]constbar=[5,18,32,newSet,{user:’EleanorRoosevelt’}];bar.sort();//returns[18,32,5,{user:’EleanorRoosevelt’},Set{}]

你可能会好奇为啥32排在5之前。发生这种情况是因为数组中的每个元素都首先转换为字符串,并且按照Unicode顺序,”32″在”5″之前。

需要注意的是,Array.sort会更改原数组。

constbaz=[‘Mycatatemyhomework’,37,9,5,17];baz.sort();//baz数组被修改console.log(baz);//shows[17,37,5,9,’Mycatatemyhomework’]

为避免这种情况,我们可以创建要排序的数组的新实例,然后在新的数组上进行修改。这里可以使用 Array.slice它返回是一个新的数组实例。

//创建baz数组的新实例并对其进行排序constsortedBaz=baz.slice().sort();

我们还可以使用 ES6 中的展开运算符来做:

constsortedBaz=[…baz].sort();

在两种情况下,输出是相同的:

console.log(baz);//[‘Mycatatemyhomework’,37,9,5,17];console.log(sortedBaz);//[17,37,5,9,’Mycatatemyhomework’]

单独使用Array.sort不能对对象数组进行排序。但不必担心,sort 的还提供一个参数,该参数使数组元素根据compare函数的返回值进行排序。

使用比较函数进行排序

假设foo和bar是compare函数要比较的两个元素,compare函数的返回值设置如下:

小于0:foo在bar之前大于0 :bar在foo之前等于0:foo和bar彼此保持不变。

来看一个简单的示例:

constnums=[79,48,12,4];functioncompare(a,b){if(a>b)return1;if(b>a)return-1;return0;}nums.sort(compare);//=>4,12,48,79

我们可以稍微重构一下:

functioncompare(a,b){returna-b;}

使用在使用箭头函数进行重构:

nums.sort((a,b)=>a-b);如何对对象数组进行排序

现在,我们来按一下对对象数组的排序。假设有下面的 singers 数组:

constsingers=[{name:’StevenTyler’,band:’Aerosmith’,born:1948},{name:’KarenCarpenter’,band:’TheCarpenters’,born:1950},{name:’KurtCobain’,band:’Nirvana’,born:1967},{name:’StevieNicks’,band:’FleetwoodMac’,born:1948},];

我们可以使用 compare函数,然后根据 singers 中的 band 字段来进行排序。

functioncompare(a,b){//使用toUpperCase()忽略字符大小写constbandA=a.band.toUpperCase();constbandB=b.band.toUpperCase();letcomparison=0;if(bandA>bandB){comparison=1;}elseif(bandA<bandB){comparison=-1;}returncomparison;}singers.sort(compare);/*returns[{name:’StevenTyler’,band:’Aerosmith’,born:1948},{name:’StevieNicks’,band:’FleetwoodMac’,born:1948},{name:’KurtCobain’,band:’Nirvana’,born:1967},{name:’KarenCarpenter’,band:’TheCarpenters’,born:1950}]*/

如果要让上面的顺序相反,可以这么做:

functioncompare(a,b){…//乘以-1来反转返回值returncomparison*-1;}创建一个动态排序函数

最后,排序函数更具动态性。

我们创建一个排序函数,可以使用该函数对一组对象进行排序,这些对象的值可以是字符串或数字。该函数有两个参数-我们要排序的键和返回结果的顺序(即升序或降序):

constsingers=[{name:’StevenTyler’,band:’Aerosmith’,born:1948},{name:’KarenCarpenter’,band:’TheCarpenters’,born:1950},{name:’KurtCobain’,band:’Nirvana’,born:1967},{name:’StevieNicks’,band:’FleetwoodMac’,born:1948},];functioncompareValues(key,order=’asc’){returnfunctioninnerSort(a,b){if(!a.hasOwnProperty(key)||!b.hasOwnProperty(key)){//该属性在其中一个对象上不存在return0;}constvarA=(typeofa[key]===’string’)?a[key].toUpperCase():a[key];constvarB=(typeofb[key]===’string’)?b[key].toUpperCase():b[key];letcomparison=0;if(varA>varB){comparison=1;}elseif(varA<varB){comparison=-1;}return((order===’desc’)?(comparison*-1):comparison);};}

使用:

//数组按`band`排序,默认为升序singers.sort(compareValues(‘band’));//数组按`band`降序排序singers.sort(compareValues(‘band’,’desc’));//数组按`name`升序排序singers.sort(compareValues(‘name’));//数组born降序排序singers.sort(compareValues(‘born’,’desc’));

在上面的代码中,hasOwnProperty方法用于检查指定的属性是否在每个对象上定义,且没有通过原型链继承。如果没有在两个对象上定义,函数返回0,排序顺序保持不变(即对象之间保持不变)。

typeof运算符还用于检查属性值的数据类型,这使函数可以确定对数组进行排序的正确方法。如果指定属性的值是一个字符串,则使用toUpperCase方法将其所有字符都转换为大写,因此排序时将忽略字符大小写

最后,你可以根据自己需求来调整上面的函数。

String.prototype.localeCompare()

在上面的示例中,我们希望能够对对象数组进行排序,其值可以是字符串或数字。但是,如果我们知道处理值是字符串的对象,则可以使用 JS 的localeCompare方法

比较两个字符串,并返回下列值中的一个:

如果 字符串 在 字母 表中 应该 排在 字符串 参数 之前, 则 返回 一个 负数;如果 字符串 等于 字符串 参数, 则 返回 0;字符串 在 字母 表中 应该 排在 字符串 参数 之后, 则 返回 一个 正数;[‘bjork’,’Bjork’,’Bj??rk’].sort();//[‘Bjork’,’Bj??rk’,’bjork’][‘bjork’,’Bjork’,’Bj??rk’].sort((a,b)=>a.localeCompare(b));//[‘bjork’,’Bjork’,’Bj??rk’]

根据compareValues函数,我们可以这么写:

functioncompareValues(key,order=’asc’){returnfunctioninnerSort(a,b){if(!a.hasOwnProperty(key)||!b.hasOwnProperty(key))return0;constcomparison=a[key].localeCompare(b[key]);return((order===’desc’)?(comparison*-1):comparison);};}总结

上面就是使用普通JS 函数对对象数组排序的简短的介绍。尽管许多库都提供了这种动态排序能力,但我们自己实现这个方法其实也不信。另外,了解幕后发生了对我们来说并没有坏处。

今天就跟大家分享到这里了,感谢大家的观看,我们下期再见。

????爱心三连击

发表评论

登录后才能评论