JS 排序神器 sort 的正确打开方式

在前端开发中,Array.prototype.sort 是一个高频使用的方法。它不仅能满足简单的排序需求,还能借助自定义比较函数解决复杂问题。本文将带你深入理解 sort 的用法,并通过一道经典的算法题 「最大数问题」(LeetCode 179) 展示 sort 的实际应用。


一、JS 中的 sort 方法详解

1. 基础用法

js 复制代码
const arr = [3, 1, 4, 1, 5, 9]
arr.sort()
console.log(arr) // [1, 1, 3, 4, 5, 9] ???

很多人以为这里输出一定是按数值升序,但实际上 JS 默认是按字符串的字典序排序

  • 内部会先将元素转为字符串
  • 然后逐字符比较 ASCII/Unicode 编码

所以 [3, 1, 4, 1, 5, 9] 默认排序结果是 [1, 1, 3, 4, 5, 9],但如果有两位数,就会出问题:

js 复制代码
[10, 2, 30].sort() // [10, 2, 30](按字典序 "1", "2", "3"...)

2. 自定义比较函数

为了按数值大小排序,我们需要传入一个 比较函数

js 复制代码
arr.sort((a, b) => a - b) // 升序
arr.sort((a, b) => b - a) // 降序
  • 如果返回值 < 0,表示 a 排在 b 前面
  • 如果返回值 > 0,表示 a 排在 b 后面
  • 如果返回值 = 0,顺序不变

例如:

js 复制代码
[10, 2, 30].sort((a, b) => a - b) // [2, 10, 30]

3. 排序稳定性

在 ES2019 之后,V8 引擎对 sort 进行了优化,保证了 稳定排序

这意味着如果两个元素相等,排序后它们的相对位置不变,这在实际业务中很重要。


二、sort 的应用案例:最大数问题(LeetCode 179)

题目描述

给定一组非负整数,重新排列它们的顺序,使其组成的数最大。

示例

输入:[3, 30, 34, 5, 9]

输出:"9534330"

解题思路

  1. 普通的数值排序不能解决这个问题,比如 303 的顺序很关键:
    • "330" < "303",所以 3 应该排在 30 前面。
  2. 我们需要自定义比较规则:
    • 对于 ab,比较 a+bb+a 的大小(字符串拼接后比较)。
    • 如果 a+b > b+a,则 a 应该排在前面。

代码实现

ts 复制代码
function largestNumber(nums: number[]): string {
  nums.sort((a, b) => {
    const ab = a.toString() + b.toString()
    const ba = b.toString() + a.toString()
    return ba.localeCompare(ab) // 保证大的排前面
  })

  const result = nums.join('')
  return result[0] === '0' ? '0' : result
}

// 示例
console.log(largestNumber([3, 30, 34, 5, 9])) // "9534330"

复杂度分析

  • 排序:O(n log n)
  • 拼接字符串:O(n)
  • 总体:O(n log n)

三、总结

  • JS 中 sort 默认按字符串字典序排序,要按数值大小排序必须传入比较函数。
  • sort 的比较函数遵循:负数 → 前面,正数 → 后面,零 → 保持位置。
  • 最大数问题sort 的经典应用,通过自定义比较逻辑,可以解决复杂的排序场景。

👉 以后遇到类似问题,不妨先想一想:能不能把问题转化为 "定义一个合适的比较规则" ,然后交给 sort 去完成?

相关推荐
Cx330❀17 分钟前
《C++ 多态》三大面向对象编程——多态:虚函数机制、重写规范与现代C++多态控制全概要
开发语言·数据结构·c++·算法·面试
_dindong19 分钟前
【递归、回溯、搜索】专题六:记忆化搜索
数据结构·c++·笔记·学习·算法·深度优先·哈希算法
努力学算法的蒟蒻22 分钟前
day03(11.1)——leetcode面试经典150
java·算法·leetcode
yugi98783823 分钟前
C语言多进程创建和回收
linux·c语言·算法
极客数模36 分钟前
【浅析赛题,一等奖水平】思路模型数据相关资料!2025 年“大湾区杯”粤港澳金融数学建模竞赛B 题 稳定币的综合评价与发展分析~
大数据·算法·数学建模·金融·数据挖掘·图论·1024程序员节
泷羽Sec-静安38 分钟前
Less-7 GET-Dump into outfile-String
android·前端·网络·sql·安全·web安全
深入理解GEE云计算1 小时前
遥感生态指数(RSEI):理论发展、方法论争与实践进展
javascript·人工智能·算法·机器学习
IT_陈寒1 小时前
从2秒到200ms:我是如何用JavaScript优化页面加载速度的🚀
前端·人工智能·后端
天天向上10241 小时前
vue 网站导航栏
前端·javascript·vue.js
云外天ノ☼1 小时前
一、Node.js入门实战指南:从零搭建你的第一个后端
前端·javascript·笔记·node.js