Javascript 从入门到精通之如何在JavaScript中对对象数组进行排序
小职 2020-11-26 来源 :大迁世界 阅读 1149 评论 0

摘要:本篇介绍了如何在javascript中对对象数组进行排序,希望对于Web前端Javascript的学习有所帮助。

本篇介绍了如何在javascript中对对象数组进行排序,希望对于Web前端Javascript的学习有所帮助。

Javascript 从入门到精通之如何在JavaScript中对对象数组进行排序

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

 

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

 

基本数组排序

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

 

const foo = [9, 1, 4, 'zebroid', 'afterdeck'];

foo.sort(); // returns [ 1, 4, 9, 'afterdeck', 'zebroid' ]

 

const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }];

bar.sort(); // returns [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]

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

 

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

 

const baz = ['My cat ate my homework', 37, 9, 5, 17];

baz.sort(); // baz数组被修改

console.log(baz); // shows [ 17, 37, 5, 9, 'My cat ate my homework' ]

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

 

// 创建baz数组的新实例并对其进行排序

const sortedBaz = baz.slice().sort();

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

 

const sortedBaz = [...baz].sort();

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

 

console.log(baz); // ['My cat ate my homework', 37, 9, 5, 17];

console.log(sortedBaz); // [ 17, 37, 5, 9, 'My cat ate my homework' ]

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

 

使用比较函数进行排序

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

 

小于0:foo在bar之前

大于0 :bar在foo之前

等于0:foo和bar彼此保持不变。

来看一个简单的示例:

 

const nums = [79, 48, 12, 4];

 

function compare(a, b) {

  if (a > b) return 1;

  if (b > a) return -1;

 

  return 0;

}

 

nums.sort(compare);

// => 4, 12, 48, 79

我们可以稍微重构一下:

 

function compare(a, b) {

  return a - b;

}

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

 

nums.sort((a, b) => a - b);

如何对对象数组进行排序

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

 

const singers = [

  { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },

  { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },

  { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },

  { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },

];

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

 

function compare(a, b) {

  // 使用 toUpperCase() 忽略字符大小写

  const bandA = a.band.toUpperCase();

  const bandB = b.band.toUpperCase();

 

  let comparison = 0;

  if (bandA > bandB) {

    comparison = 1;

  } else if (bandA < bandB) {

    comparison = -1;

  }

  return comparison;

}

 

singers.sort(compare);

 

/* returns [

  { name: 'Steven Tyler', band: 'Aerosmith',  born: 1948 },

  { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },

  { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },

  { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }

] */

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

 

function compare(a, b) {

  ...

 

  // 乘以-1来反转返回值

  return comparison * -1;

}

创建一个动态排序函数

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

 

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

 

const singers = [

  { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },

  { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },

  { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },

  { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },

];

 

function compareValues(key, order = 'asc') {

  return function innerSort(a, b) {

    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {

      // 该属性在其中一个对象上不存在

      return 0;

    }

 

    const varA = (typeof a[key] === 'string')

      ? a[key].toUpperCase() : a[key];

    const varB = (typeof b[key] === 'string')

      ? b[key].toUpperCase() : b[key];

 

    let comparison = 0;

    if (varA > varB) {

      comparison = 1;

    } else if (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函数,我们可以这么写:

 

function compareValues(key, order = 'asc') {

  return function innerSort(a, b) {

    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) return 0;

    const comparison = a[key].localeCompare(b[key]);

 

    return (

      (order === 'desc') ? (comparison * -1) : comparison

    );

  };

}

总结

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



关注“职坐标在线”(Zhizuobiao_Online)公众号,免费获取源码资料、技术就业咨询。

Javascript 从入门到精通之如何在JavaScript中对对象数组进行排序

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved