当前位置:嗨网首页>书籍在线阅读

11-数组搜索

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

8.3 数组搜索

如果想在数组中查找元素,有以下几种选择。从最简单的 indexOf 开始介绍,JavaScript很久以前就开始支持它了。 indexOf 将返回跟所要查找的内容完全相同的第一个元素的下标(对应的还有 lastIndexOf() ,从数组末尾开始查找,同样返回完全匹配的第一个元素的下标)。如果只想在数组的某一部分查找,可以指定查找的起始下标。如果 indexOf (或者 lastIndexOf() )返回−1,则表示没有匹配的元素:

const o = { name: "Jerry" };
const arr = [1, 5, "a", o, true, 5, [1, 2], "9"];
arr.indexOf(5);                      // returns 1
arr.lastIndexOf(5);                  // returns 5
arr.indexOf("a");                    // returns 2
arr.lastIndexOf("a");                // returns 2
arr.indexOf({ name: "Jerry" });      // returns -1
arr.indexOf(o);                      // returns 3
arr.indexOf([1, 2]);                 // returns -1
arr.indexOf("9");                    // returns 7
arr.indexOf(9);                      // returns -1
arr.indexOf("a", 5);                 // returns -1
arr.indexOf(5, 5);                   // returns 5
arr.lastIndexOf(5, 4);               // returns 1
arr.lastIndexOf(true, 3);            // returns -1

另一个查找元素的方法是 findIndex ,它与 indexOf 一样,返回一个下标(返回−1表示没有匹配元素)。相比于 indexOffindIndex 更灵活,因为它可以指定一个函数来表示元素是否匹配( findIndex 不能指定查找的起始位置,不过它有对应的 findLastIndex 函数):

const arr = [{ id: 5, name: "Judith" }, { id: 7, name: "Francis" }];
arr.findIndex(o => o.id === 5);                // returns 0
arr.findIndex(o => o.name === "Francis");      // returns 1
arr.findIndex(o => o === 3);                   // returns -1
arr.findIndex(o => o.id === 17);               // returns -1

find 还是一个用于查找的方法,它和 findIndex 都很适合查找特定元素的下标。不过,如果并不关心元素下标,只想返回元素本身呢?像 findIndex 一样, find 也允许指定一个函数来进行查找,只不过它会返回元素本身而非元素下标(没找到元素时返回 null )。

const arr = [{ id: 5, name: "Judith" }, { id: 7, name: "Francis" }];
arr.find(o => o.id === 5);   // returns object { id: 5, name: "Judith" }
arr.find(o => o.id === 2);   // returns null

那些传入 findfindIndex 中的函数,会把数组的每一个元素作为第一个参数,其他参数还有当前元素的下标和数组本身。它们可以完成这样一些事情,比如:寻找以指定下标开始的元素的平方数。

const arr = [1, 17, 16, 5, 4, 16, 10, 3, 49];
arr.find((x, i) => i > 2 && Number.isInteger(Math.sqrt(x)));// returns 4

findfindIndex 还允许在方法调用过程中指定 this 变量使用的值。它们可以用在需要调用某个对象方法的场景中。以下这些方法都会在 Person 对象中通过ID来查找元素,对比一下这些实现:

class Person {
   constructor(name) {
      this.name = name;
      this.id = Person.nextId++;
   }
}
Person.nextId = 0;
const jamie = new Person("Jamie"),
   juliet = new Person("Juliet"),
   peter = new Person("Peter"),
   jay = new Person("Jay");
const arr = [jamie, juliet, peter, jay];
// 选项 1: 直接比较ID:
arr.find(p => p.id === juliet.id);           // 返回juliet 对象
// 选项2: 使用 "this"参数:
arr.find(function(p)(return p.id === this.id, juliet); // 返回 juliet 对象

大家可能会发现在 findfindIndex 中, this 值的作用是有限的。但实际上这是后面会讲到的技术,届时它将会变得更加实用。

正如并不总关心数组中元素的索引一样,有时候甚至不关心下标或是元素本身,只想单纯的知道这个元素是否存在。显然,可以使用之前提到的函数来检查元素是否存在,看它是返回−1还是 null ,不过,JavaScript专门提供了两个方法来解决这个问题: someevery

一旦找到符合条件的元素(只需要一个符合条件的元素,所以在找到第一个元素后会停止查找), some 方法就会返回 true ,否则返回 false 。例如:

const arr = [5, 7, 12, 15, 17];
arr.some(x => x%2===0);                          // true; 12 是偶数
arr.some(x => Number.isInteger(Math.sqrt(x)));   // false; 没有平方数

而当数组中的每个元素都符合条件的时候, every 方法才会返回 true ,否则返回 false 。当 every 方法发现一个不符合条件的元素时,就会停止查找并返回 false ;否则,会扫描整个数组:

const arr = [4, 6, 16, 36];
arr.every(x => x%2===0);                         // true; 没有奇数
arr.every(x => Number.isInteger(Math.sqrt(x)));  // false; 6不是平方数

像本章中所提及的其他方法一样, someevery 也可以接收一个方法作为参数,它们还能再接收一个参数,用来指定方法被调用时的 this 值。