Files
2026-07-13 21:36:17 +08:00

84 lines
2.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Use Loop for Min/Max Instead of Sort
impact: LOW
impactDescription: O(n) 替代 O(n log n)
tags: javascript, arrays, performance, sorting, algorithms
---
## Use Loop for Min/Max Instead of Sort
寻找最小或最大元素只需遍历数组一次。排序既浪费又低效。
**错误做法(O(n log n)——通过排序找最新值):**
```typescript
interface Project {
id: string
name: string
updatedAt: number
}
function getLatestProject(projects: Project[]) {
const sorted = [...projects].sort((a, b) => b.updatedAt - a.updatedAt)
return sorted[0]
}
```
仅仅为了找到最大值就对整个数组进行排序。
**错误做法(O(n log n)——通过排序找最旧和最新值):**
```typescript
function getOldestAndNewest(projects: Project[]) {
const sorted = [...projects].sort((a, b) => a.updatedAt - b.updatedAt)
return { oldest: sorted[0], newest: sorted[sorted.length - 1] }
}
```
当只需要最小/最大值时,仍然进行了不必要的排序。
**正确做法(O(n)——单次循环):**
```typescript
function getLatestProject(projects: Project[]) {
if (projects.length === 0) return null
let latest = projects[0]
for (let i = 1; i < projects.length; i++) {
if (projects[i].updatedAt > latest.updatedAt) {
latest = projects[i]
}
}
return latest
}
function getOldestAndNewest(projects: Project[]) {
if (projects.length === 0) return { oldest: null, newest: null }
let oldest = projects[0]
let newest = projects[0]
for (let i = 1; i < projects.length; i++) {
if (projects[i].updatedAt < oldest.updatedAt) oldest = projects[i]
if (projects[i].updatedAt > newest.updatedAt) newest = projects[i]
}
return { oldest, newest }
}
```
只需单次遍历数组,无需复制,无需排序。
**备选方案(对小型数组使用 Math.min/Math.max):**
```typescript
const numbers = [5, 2, 8, 1, 9]
const min = Math.min(...numbers)
const max = Math.max(...numbers)
```
这种方法适用于小型数组,但对于非常大的数组,由于展开运算符的限制,可能会变慢甚至抛出错误。Chrome 143 中的最大数组长度约为 124000Safari 18 中约为 638000;具体数值可能有所不同——详见 [jsfiddle](https://jsfiddle.net/qw1jabsx/4/)。为了可靠性,请使用循环方案。