侧边栏壁纸
  • 累计撰写 238 篇文章
  • 累计创建 289 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

JavaScript数组专题之3:数组的查找与判断方法大全

DGF
DGF
2025-09-28 / 0 评论 / 0 点赞 / 4 阅读 / 0 字

JS 数组系列专题文章目录

入门篇

第 1 篇:认识 JavaScript 数组——从入门到操作基础
👉 介绍数组的概念、创建方式、索引与长度的使用,以及最基础的遍历方法。适合刚接触数组的新手。

第 2 篇:数组的增删改全解析(push、pop、splice)
👉 系统讲解数组的增删改方法,包括 pushpopshiftunshiftsplicefill,并结合小案例说明。

常用方法篇

第 3 篇:数组的查找与判断方法大全
👉 详细介绍如何在数组中查找元素,包括 indexOflastIndexOfincludesfindfindIndexsomeevery 等。

第 4 篇:数组的排序与合并技巧(sort、concat、slice)
👉 讲解数组排序与反转的方法,以及合并、切片、字符串化的常见操作,重点讲解 sort 排序中的注意点。

进阶篇

第 5 篇:数组的迭代与转换(map、filter、reduce 全解)
👉 深入剖析高阶方法 mapfilterreduce,包括实际应用场景:数组求和、数据统计、扁平化处理等。

第 6 篇:数组的实用技巧与案例集锦
👉 介绍常见的数组处理技巧:去重(多种写法对比)、扁平化(flat 与递归实现)、字符串与数组互转、对象数组排序。

高阶篇

第 7 篇:类数组与稀疏数组——容易忽略的细节
👉 解释什么是类数组(argumentsNodeList),如何转换为真数组,稀疏数组的特性和坑点。

第 8 篇:不可变数组操作与函数式编程思路
👉 如何在不修改原数组的前提下进行操作(扩展运算符、concatmap 等),结合函数式编程的思想讲解。

实战 & 面试篇

第 9 篇:手写数组常用方法(map、filter、reduce)
👉 从源码角度模拟实现常见数组方法,帮助加深理解,提升面试竞争力。

第 10 篇:数组实战应用与高频面试题精选
👉 总结数组在实战中的应用:两数之和、数组旋转、最大最小值查找、groupBy、分页实现,涵盖面试常考题。

常用方法与何时用它们(先上速查表)

  • includes(value) —— 询问“有没有这个值?”,返回 true/false(适合原始类型快速查存在性)。
  • indexOf(value) / lastIndexOf(value) —— 找到在数组中首次/最后一次出现的下标,找不到返回 -1(对原始类型或引用完全相等的对象有效)。indexOf 使用严格相等比较(===),因此对 NaN 找不到。
  • find(predicate) —— 返回第一个满足条件的元素(不是下标),找不到返回 undefinedpredicate 是回调函数,可写复杂条件。
  • findIndex(predicate) —— 返回第一个满足条件元素的下标,找不到返回 -1
  • some(predicate) —— 检查是否存在至少一个元素满足条件(相当于逻辑 ∃),返回布尔。
  • every(predicate) —— 检查所有元素是否都满足条件(相当于逻辑 ∀),空数组会返回 true(数学上称作“类真”/vacuously true)。另外,every / some / find 等回调只会被调用在数组中存在值的索引(稀疏数组的空位会跳过)。

(上面这些方法绝大多数都是线性扫描 —— 时间复杂度 O(n),n 很大时要注意性能)

详细讲解 + 代码示例(生活类比 + 实战)

1) includes:问一句“有吗?”

类比:把包打开问朋友:“包里有没有零食?” 他给你 是/否 回答。

const arr = [1, 2, 3, NaN];

console.log(arr.includes(2));    // true
console.log(arr.includes(5));    // false

// includes 使用 SameValueZero 比较,因此能识别 NaN
console.log(arr.includes(NaN));  // true
  • 适用场景:你只想知道有没有某个(通常是原始)值时用。它内部使用的是 SameValueZero(这也是为什么 NaN 会被判断为“相等”的原因)。

2) indexOf / lastIndexOf:要位置就找下标

类比:你问“我的公交卡放在哪个抽屉里?”朋友指给你第几个抽屉编号(下标)。

const a = ['a', 'b', 'a', 'c'];

console.log(a.indexOf('a'));      // 0  (第一个出现位置)
console.log(a.lastIndexOf('a'));  // 2  (最后一个出现位置)
console.log(a.indexOf('x'));      // -1 (没找到)

注意:

  • indexOf 使用严格相等(===),所以 NaN 永远找不到(返回 -1)。如果你需要判断存在性,考虑 includesindexOf 会跳过稀疏数组的空位。

3) find:找到“第一个符合条件的那个人”,返回元素本身

类比:你从人群里问“谁带了雨伞?”,那第一个举手的人就是你要的那位。

const users = [
  { id: 1, name: '小明', vip: false },
  { id: 2, name: '小红', vip: true },
  { id: 3, name: '小李', vip: true },
];

// 找到第一个 vip 用户
const firstVip = users.find(u => u.vip);
console.log(firstVip); // { id: 2, name: '小红', vip: true }

// 找不到时返回 undefined
console.log(users.find(u => u.id === 99)); // undefined
  • find 的回调接收三个参数:(element, index, array),并可带可选 thisArg。如果需要下标,改用 findIndex

4) findIndex:找下标(为 splice / 替换等场景准备)

const fruits = ['苹果', '香蕉', '梨', '香蕉'];
const idx = fruits.findIndex(f => f === '香蕉');
console.log(idx); // 1

if (idx !== -1) {
  fruits.splice(idx, 1); // 删除第一个香蕉
}
  • findIndex 找不到时返回 -1。适合你需要知道元素位置以便后续修改/删除时使用。

5) some vs every:布尔量的“有/全”

类比:

  • some:队里有没有能唱高音的人?(存在一个就够)
  • every:队里所有人都会唱歌吗?(每个人都要会)
const scores = [80, 90, 100];

console.log(scores.some(s => s < 60)); // false(有没有不及格的)
console.log(scores.every(s => s >= 60)); // true(是否都及格)

// 空数组例子
console.log([].some(x => x > 0));   // false(没元素,自然不存在满足的)
console.log([].every(x => x > 0));  // true(数学上的“全都满足”对空集成立)
  • every 对空数组返回 truesome 对空数组返回 false。这是数学逻辑的自然延伸(空集的“全真”)。另外,这些回调也会跳过稀疏数组的空位(不会被调用)。

6) find vs filter:找第一条还是找全部?

  • find:返回第一个匹配项(或者 undefined
  • filter:返回所有匹配项的新数组(可能是空数组 []
const arr = [1,2,3,4,5,6];

// 找第一个偶数
console.log(arr.find(x => x % 2 === 0));   // 2

// 找所有偶数
console.log(arr.filter(x => x % 2 === 0)); // [2,4,6]

选择规则:要单个直接 find,要集合用 filter

7) 对象数组和引用类型的坑

const o1 = {name: 'A'};
const o2 = {name: 'A'};
const arr = [o1];

console.log(arr.indexOf(o1)); // 0  (同一个引用)
console.log(arr.indexOf(o2)); // -1 (内容一样,但引用不是同一个)
  • indexOf/includes/lastIndexOf 对于对象比较的是引用(同一个对象实例才相等)。如果想按对象属性查找,用 find
const found = arr.find(x => x.name === 'A');

8) findLast / findLastIndex(新朋友)

如果你想从右往左找(找到最后一个满足条件的元素/下标),标准里已经有 findLastfindLastIndex 可以用,不过它们在某些旧环境可能还不支持(要注意兼容性或 polyfill)。如果环境不支持,可以手动反转数组或倒序遍历。

9) 关于稀疏数组(空位)和回调方法

许多回调式方法(forEachmapfilterfindsomeevery 等)在遇到稀疏数组的“空位”时,会跳过不调用回调(也就是说回调只会被调用在那些已有值的索引上)。这点在处理稀疏数组时要留个心。

记住这几句口诀

  • “有没?”用 includes;要下标用 indexOf/findIndex;要元素用 find
  • indexOf===(无法识别 NaN),includes 用 SameValueZero(可识别 NaN)。
  • some = 存在性(∃),every = 全符合(∀,空数组返回 true)。
0

评论区