点击上方“前端自习课”关注,学习起来~

英文原文:[《Usar correctamente el método sort()》]
文章地址:查看阅读原文。
注意:内容有做精简和调整。

在过去的几个星期里,我们在不同的团队中看到,一般来说都没有使用 Array.prototype.sort()的习惯,并且不知道这种方法是如何工作的。今天我们将尝试简要描述它是如何工作的 .sort(),揭示它的一些秘密。

1. 修改原数组

在这种情况下,我们必须记住,此方法通过对数组进行排序来修改数组返回相同的有序数组,但不返回新数组。如果我们想要保持数组不可变并获得另一个排序,这一点很重要,我们必须在排序之前制作数组的拷贝。

2. 字符串在 Unicode 代码中的位置比较

默认情况下, .sort() 方法会根据 Unicode 代码中每个字母的位置将数组值排序为字符串,因此您可以对此数组进行排序而不会出现问题:


  1. console.log(["Zaragoza", "Madrid", "Barcelona"].sort());.log(["Zaragoza", "Madrid", "Barcelona"].sort());
  2. // [ 'Barcelona', 'Madrid', 'Zaragoza' ]

这似乎是正确的,但是如果和一些名称以小写字母开头,那么排序似乎不正确:


  1. console.log(["Zaragoza", "madrid", "Barcelona"].sort());.log(["Zaragoza", "madrid", "Barcelona"].sort());
  2. // [ 'Barcelona', 'Zaragoza', 'madrid' ]

在这种情况下,排序是在 Unicode 代码表中的每个字母的位置之后完成的,并且 m 落后 Z ,因此它已经以这种方式排序。

如果我们想对数字排序,事情就会变得复杂起来:


  1. console.log([80, 9, 100].sort());.log([80, 9, 100].sort());
  2. // [ 100, 80, 9 ]

结果似乎很荒谬,但这是有道理的,发生的事情是数字已被转换为字符串,因此被比较的是字符串 "100", "80"并且 "9"。由于它们在 Unicode 代码中的位置是按顺序的,因此排序是正确的,即使它不是我们最初的预期。

这些情况的产生导致一些人放弃使用 .sort() 产生混乱的行为。这有点草率,因为只需一点帮助,这种方法可以毫无问题地运行。

3. Sort() 方法参数

该 .sort() 有一个可选参数允许此方法帮助对内容进行排序。这是此方法的关键,因为我们对每种情况都感兴趣。

此函数接收两个要比较的值,因此也会有这么三种情况:

  • 如果第一个值大于第二个值,则返回正值 ( 1);

  • 如果第一个值小于第二个值,则返回负值 ( -1);

  • 如果两个值相等或等效于排序,则返回零值 ( 0);

这个函数由 Javascript 调用,只要您需要对数组中的元素进行排序,我们就可以进行必要的比较和调整。例如,为了比较数字,我们可以使用类似方法:


  1. console.log([80, 9, 100].sort((a, b) => a - b));.log([80, 9, 100].sort((a, b) => a - b));
  2. // [ 9, 80, 100 ]

另外, (a,b)=>a–b 还可以这么使用:使用其中一个值 a 去判断是否大于另一个值 b 来返回排序结果:


  1. const data = [ "Zaragoza", "madrid", "Barcelona" ]; data = [ "Zaragoza", "madrid", "Barcelona" ];
  2. data.sort ((a, b) => a.toLowerCase () > b.toLowerCase ());.sort ((a, b) => a.toLowerCase () > b.toLowerCase ());
  3. console.log (data);.log (data);
  4. // [ 'Zaragoza', 'madrid', 'Barcelona' ]

显然结果不正确,因为我们草率的将函数比较的结果 true 或者 false 返回,我们必须记住支持函数 .sort() 希望我们返回 -1 , 1 或者 0。为了使它正常运行,我们必须做修改:


  1. const data = [ "Zaragoza", "madrid", "Barcelona" ]; data = [ "Zaragoza", "madrid", "Barcelona" ];
  2. data.sort ((a, b) =>.sort ((a, b) =>
  3.   a.toLowerCase() > b.toLowerCase() ? 1 :.toLowerCase() > b.toLowerCase() ? 1 :
  4.   a.toLowerCase() < b.toLowerCase() ? -1:.toLowerCase() < b.toLowerCase() ? -1:
  5.   00
  6. );
  7. console.log (data);.log (data);
  8. // [ 'Barcelona', 'madrid', 'Zaragoza' ]

现在的结果是我们需要的,因为我们已经对小写和大写也进行了比较,并且我们已经返回 -1, 1或者 0根据每种情况。

我们还没有真正完成,因为如果我们加入一些重音字母,我们会得到一个不希望的结果:


  1. const data = [ "Zaragoza", "madrid", "Barcelona", "Ávila" ]; data = [ "Zaragoza", "madrid", "Barcelona", "Ávila" ];
  2. data.sort ((a, b) =>.sort ((a, b) =>
  3.   a.toLowerCase() > b.toLowerCase() ? 1 :.toLowerCase() > b.toLowerCase() ? 1 :
  4.   a.toLowerCase() < b.toLowerCase() ? -1:.toLowerCase() < b.toLowerCase() ? -1:
  5.   00
  6. );
  7. console.log (data);.log (data);
  8. // [ 'Barcelona', 'madrid', 'Zaragoza', 'Ávila' ]

当我们想对文本字符串进行排序,就非常有必要使用 .localeCompare() 方法,也是非常重要。

4. 用对象属性排序数组

通常,如果数组包含对象,我们可以使用对象的属性进行比较,例如:


  1. const data = require ('./municipios.json'); data = require ('./municipios.json');
  2. data.sort ((a, b) => a.municipio.localeCompare (b.municipio));.sort ((a, b) => a.municipio.localeCompare (b.municipio));

我们可以对数据结构中的日期和任何其他类型的对象执行相同的操作。

5. 关于性能方面

如果我们想对非常大的数组进行排序,我们必须记住。 sort() 方法的支持函数将被多次调用,我们必须避免在这个函数中执行许多操作或非常重的操作。我们必须尽可能有效地进行比较。

例如,在非常大的数组中,可以使用新的方法 Int.Collate().compare 来获得更有效的排序函数,而不是使用 .localecompare()。 Int 对象是名为 InternationalAPI ,也是 ECMA-402 的标准的一部分,

该标准侧重于国际化功能,包括每种语言的正确排序。 Int 在浏览器和节点中以全局对象的形式呈现,并具有广泛的支持(包括IE11)。


  1. const data    = [ "Zaragoza", "Ávila", "madrid", "Barcelona" ]; data    = [ "Zaragoza", "Ávila", "madrid", "Barcelona" ];
  2. const compare = new Intl.Collator ().compare; compare = new Intl.Collator ().compare;
  3. data.sort (compare);.sort (compare);
  4. console.log (data);.log (data);
  5. // [ 'Ávila', 'Barcelona', 'madrid', 'Zaragoza' ]

排序操作很复杂,性能也很差,因此对于非常大的数组,排序方法支持函数速度的任何改进都将对性能产生非常显著的影响。

6. 总结

一般来说,我们应该利用 .sort() 功能和一个支持函数来控制排序应该如何执行:

  • 数字: (a,b)=>a–b

  • 链式: (a,b)=>a.localeCompare(b)

在没有函数参数的情况下使用 .sort() 是没有意义的,也许在少数情况下是这样,但是如果我们用一个简单的函数支持它,那么 .sort 是一个非常有用的工具。

在许多情况下,排序是一个基本的操作,我们不应该放弃在Javascript中进行这种排序。

关于我

本文首发在 [pingan8787个人博客] (http://www.pingan8787.com),如需转载请保留个人介绍。

▼原创系列推荐▼1.JavaScript 重温系列(22篇全)
2.ECMAScript 重温系列(10篇全)
3.JavaScript设计模式 重温系列(9篇全)
4.正则 / 框架 / 算法等 重温系列(16篇全)

你点的每个赞,我都认真当成了喜欢

【JS】297-[译]正确使用 sort() 方法的更多相关文章

  1. js数组排序 reverse()和sort()方法的使用

    WEB前端|js数组排序reverse()和sort()方法的使用,数组中已经存在两个可以直接用来重排序的方法:reverse()和sort(). reverse()方法会对反转数组项的顺序. var ...

  2. js 排序:sort()方法、冒泡排序、二分法排序。

    js中的排序,这里介绍三种,sort()方法.冒泡排序.二分法排序. 1.sort方法 写法:  数组.sort(); 返回排好序的数组,如果数组里是数字,则由小到大,如果是字符串,就按照第一个字符的 ...

  3. js中的数组对象排序(方法sort()详细介绍)

    定义和用法 sort() 方法用于对数组的元素进行排序. 语法    arrayObject.sort(sortby) 参数sortby:可选.规定排序顺序.必须是函数. 返回值 对数组的引用.请注意 ...

  4. 基于原生JS封装数组原型上的sort方法

    基于原生JS封装数组原型上的sort方法 最近学习了数组的原型上内置方法的封装,加强了用原生JS封装方法的能力,也进一步理解数组方法封装的过程,实现的功能.虽然没有深入底层,了解源码.以下解法都是基于 ...

  5. js sort方法根据数组中对象的某一个属性值进行排序(实用方法)

    js sort方法根据数组中对象的某一个属性值进行排序 sort方法接收一个函数作为参数,这里嵌套一层函数用来接收对象属性名,其他部分代码与正常使用sort方法相同. var arr = [ {nam ...

  6. JS基础篇--sort()方法的用法,参数以及排序原理

    JS基础篇--sort()方法的用法,参数以及排序原理   sort() 方法用于对数组的元素进行排序,并返回数组.默认排序顺序是根据字符串Unicode码点.语法:arrayObject.sort( ...

  7. JS高级面试题思路(装箱和拆箱、栈和堆、js中sort()方法、.js中Date对象中的getMounth() 需要注意的、开发中编码和解码使用场景有哪些)

    1.装箱和拆箱: 装箱:把基本数据类型转化为对应的引用数据类型的操作: var num = 123 // num var objNum = new Num(123) // object console ...

  8. js 自带的 sort() 方法

    1. 方法概述 Array的sort()方法默认把所有元素先转换为String再根据Unicode排序, sort()会改变原数组,并返回改变(排序)后的数组 . 2. 例子 2.1 如果没有提供自定 ...

  9. js中的数组Array定义与sort方法使用示例

    Array的定义及sort方法使用示例 Array数组相当于java中的ArrayList  定义方法:  1:使用new Array(5  )创建数组 var ary = new Array(5): ...

随机推荐

  1. nyoj 599-奋斗的小蜗牛 (double ceil(); (temp - 1) / 5)

    599-奋斗的小蜗牛 内存限制:64MB 时间限制:1000ms 特判: No 通过数:0 提交数:96 难度:1 题目描述: 传说中能站在金字塔顶的只有两种动物,一种是鹰,一种是蜗牛.一只小蜗牛听了 ...

  2. 【Java】面向对象初探

    前段时间经历了一段心态浮躁期,这让我想起了自己最初的计划,要提升自己知识体系的广度.前几年一直做的是web前端这一块的工作,但我希望通过自己在学习Java这样的过程来提升自己的知识广度. 面向对象概述 ...

  3. 领扣(LeetCode)字母大小写全排列 个人题解

    给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串.返回所有可能得到的字符串集合. 示例: 输入: S = "a1b2" 输出: ["a1 ...

  4. C语言|博客作业01

    2.1你对计算机科学与技术的了解是怎样? 一开始,我并不知道计科和软件的区别,甚至以为这是一种专业的两种叫法.进了大学之后,才一下子懂了,计科就是计科,它和软件虽有相同之处,但是终究是不一样的.计科涉 ...

  5. sqlalchemy 源码分析之create_engine引擎的创建

    引擎是sqlalchemy的核心,不管是 sql core 还是orm的使用都需要依赖引擎的创建,为此我们研究下,引擎是如何创建的. from sqlalchemy import create_eng ...

  6. PostGIS 报错为org.postgresql.util.PSQLException:错误: Operation on mixed SRID geometries

    说明: 在用Openlayers与Geoserver进行开发,做在线编辑功能时,出现一个问题:每当我新增了一根要素后,再次用wfs的方式进行点击查询时,会报错mixed SRID. 通过研究发现在数据 ...

  7. Laravel 菜鸟的晋级之路

    第一阶段:简单的增删改查 这是最开始接触Laravel的一个阶段.如果有PHP经验,那么应该能很快找到MVC的路径,然后驾轻就熟的开始写起来.虽然还显得有些笨拙,不过很快就能做出一些内容了.如果没有P ...

  8. MySQL基础知识面试与答案

    1.Mysql 的存储引擎,myisam和innodb的区别. 答: 1.MyISAM 是非事务的存储引擎,适合用于频繁查询的应用.表锁,不会出现死锁,适合小数据,小并发. 2.innodb是支持事务 ...

  9. 网络图片的获取以及二级缓存策略(Volley框架+内存LruCache+磁盘DiskLruCache)

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  10. 扛把子组2018092609-2 选题 Scrum立会报告+燃尽图 06

    此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2019fall/homework/8681] 一.小组情况组长:迟俊文组员:宋晓丽 梁梦瑶 韩昊 刘信鹏队名 ...