今天我们来继续 Javascript 数组系列的文章,上文 《Javascript数组系列二之迭代方法1》 我们说到一些数组的迭代方法,我们在开发项目实战的过程中熟练的使用可以大大提高我们的开发效率以及数据的处理。接下来我们继续来讲解其他的一些迭代的方法。

天也黑了,时间也不早了,话不多说,撸起袖子干起来!

数组的迭代方法

reduce

该方法对一个累加值和数组中的每一个元素执行给定的函数,返回一个函数累计处理的结果。

乍一看定义好像不是很好理解,来看一个例子你就会立刻明白,简单来说该方法就是对数组进行合并操作。

const numbers = [1, 2, 3, 4, 5];
const result = numbers.reduce((sum, value) => sum + value);
console.log(result); //15

这里值得注意的是,reduce 方法的执行顺序是从左到右,为什么特意指出,因为下面我们会介绍一个从右到左的方法(reduceRight),先行了解下。

从上面的例子我们能看出「reduce」方法的作用,但是可能我们还不清楚具体的执行过程是怎么样的,继续走起!

还是按照以往的惯例,我们先来看看「reduce」的参数和语法

该方法接受两个参数,一个是元素每一项执行的回调函数;一个是可选的参数,作为第一次调用函数的初始值(也就是第一次的累加值)

传入的回调函数会接受个参数分别是:调用函数返回的累计值(accumulator),数组中当前处理的元素(currentValue),当前处理元素的索引(currentIndex,可选),数组本身(array,可选)。

//语法
array.reduce(callback[, initialValue])
array.reduce(callback(accumulator, currentValue, currentIndex, array){
    //return 合并操作
});

参数与语法认清之后,先来看两个例子

//例子1
const numbers = [1, 2, 3, 4, 5];
const result = numbers.reduce((accumulator, currentValue, currentIndex) => {
    console.log(currentIndex); //1, 2, 3, 4
    return accumulator + currentValue;
});
console.log(result); //15 //例子2
const newResult = numbers.reduce((accumulator, currentValue, currentIndex) => {
    console.log(currentIndex);  //0, 1, 2, 3, 4
    return accumulator + currentValue;
}, 10);
console.log(newResult); //25

从以上两个例子中我们也看到一些不同的输出结果,原因是因为我们给定了一个初始值之后,方法开始执行的位置发生变化,那么是如何变化的呢?

这里存在两种情况:

  1. 如果我们在使用「reduce」方法的时候,提供可选的初始值(initialValue),在回调函数第一次执行的时候,第一次的累计值会默认取值为给定的初始值,当前参与计算的元素会从数组的第一项开始
    (即:accumulator = initialValue,currentValue = array[0])

  2. 如果我们在使用「reduce」方法的时候,没有提供初始值(initialValue),那么在回调函数第一次执行的时候,第一次的累计值为数组的第一项,当前参与计算的值为数组的第二项(即: accumulator = array[0],
    currentValue = array[1])

简单来说如果我们提供初始值,回调函数会从数组的第二项(index=0)开始执行,反之回调函数会从数组的第一项开始执行(index=1),这就是上面例子中输出索引的结果不同的原因。

说了这么多,大家肯定很清楚了,那最后我们来看看 「reduce」 方法的兼容性,还是直接上图。

reduce支持的浏览器

reduceRight

从名字我们已经看出「reduceRight」与「reduce」肯定有扯不清的关系了。上面我们也说到「reduce」方法的执行顺序是从左到右。

而「reduceRight」方法的执行顺序为从右到左,除了在这一点上与「reduce」不同之外,其他地方与「reduce」一毛一样,所以我们就不做过多解释了,看一个简单的例子即可。

const numbers = [1, 2, 3, 4, 5];
const result = numbers.reduceRight((accumulator, currentValue, currentIndex) => {
    console.log(currentIndex); //3, 2, 1, 0
    return accumulator + currentValue;
});
console.log(result); //15

find

该方法对数组的每一个元素执行给定的函数,返回满足条件的元素,如果发现满足条件的值会立即返回当前元素,如果未发现满足条件的元素则返回 undefined。

该方法接受两个参数,一个是元素每一项执行的回调函数,一个是可选参数,回调函数运行时 this 的值。

传入的回调函数会接受三个参数分别是:数组中的元素(item),元素的索引(index,可选),数组本身(array,可选)。

//语法
array.find(callback[, this])
array.find(callback(item, index, array){
    //return 执行的操作
}); //例子
const numbers = [4, 9, 16, 25, 29];
const result = numbers.find((item, index)=> {
    console.log(index); //0, 1, 2
    return item > 10;
});
console.log(result); //16

根据案例中打印的结果与最后返回的结果来看,当找到满足条件的元素时会立刻返回结果,并终止函数的执行。可以理解为「find」方法就是在众多数据中找到一个我们想要的。

让我们来看看 「find」方法的兼容性,继续直接上图。

find支持的浏览器

findIndex

通过「find」方法聪明的你们肯定会发现「findIndex」用法。

是的「findIndex」的用法与 「find」基本相同,不同的是「findIndex」返回的是我们满足条件元素的索引,而「find」返回的是元素。

既然如此我们就不做过多介绍,还是利用我们在「find」方法中使用的案例。

//例子
const numbers = [4, 9, 16, 25, 29];
const result = numbers.findIndex((item)=> {
    return item > 10;
});
console.log(result); //2

虽说两者的用法基本相同,但是在没有得到满足我们条件的元素时,其两者返回的结果会略有不同。一个返回 undefined,一个返回 -1。

const numbers = [4, 9, 16, 25, 29];
const result = numbers.find((item)=> {
    return item > 30;
});
console.log(result); //undefined
const resultIndex = numbers.findIndex((item)=> {
    return item > 30;
});
console.log(resultIndex); //-1

indexOf

该方法会对给定的一个值在数组中进行查找,如果找到相同的元素则返回元素的索引,否则返回 -1 。

该方法接受两个参数:一个是要查找的元素(searchElement),一个是查找开始的位置(fromIndex,可选),默认值为 0 。

//语法
arr.indexOf(searchElement)
arr.indexOf(searchElement[, fromIndex = 0]) //案例
const numbers = [2, 3, 2, 4, 2];
console.log(numbers.indexOf(2)); //0
console.log(numbers.indexOf('2')); //-1
console.log(numbers.indexOf(2, 1)); //2
console.log(numbers.indexOf(2, -1)); //4

「indexOf」方法有几点需要我们注意的地方。

  • 在方法执行查找的过程中使用的是严格相等(===),案例中查找 '2' 时返回 -1 ,就是这个原因,如果不知道 == 与 === 有什么区别的小伙伴可以自己查阅下资料进行了解。
  • 关于第二个参数 fromIndex,如果当 fromIndex 的数值大于或者等于执行的数组长度时,就会返回 -1,因为没有地方查找了。如果查找的数值为负数,则会从数组的后面开始查找。
  • 要注意的是数组的末尾的索引是从 -1 开始的;例如:-1从数组的最后一个元素开始,-2从数组的倒数第二个元素开始。
  • 非常重要的一点是不管 fromIndex 的数值为正数还是负数「indexOf」方法的查找顺序都是从前向后执行的,案例中最后一个方法输出的是 4 而不是 2 的原因。

那有没有从后向前查找元素的方法呢?答案是肯定的,后面我们会继续说的,在这之前我们先来看一个我们在项目开发过程中经常使用的一个例子。

我们就利用上面说到的 reduce 与 indexOf 来实现一个数组简单去重的方法

const numbers = [2, 3, 2, 4, 2, 3, 1, 4];
const result = numbers.reduce((prev, current) => {
    if (prev.indexOf(current) === -1) {
        prev.push(current);
    }
    return prev;
}, []);
console.log(result); //[2, 3, 4, 1]

最后我们再来看看「indexOf」方法的兼容性。

兼容图表

lastIndexOf

「lastIndexOf」与「indexOf」用法相同;不同的是前者
是从后向前查找,后者是从前向后查找。

const numbers = [2, 3, 2, 4, 2];
console.log(numbers.lastIndexOf(2)); //4
console.log(numbers.lastIndexOf('2')); //-1
console.log(numbers.lastIndexOf(2, 1)); //0
console.log(numbers.lastIndexOf(2, -1)); //4

总结

我们花了两篇文章说了数组的一系列迭代方法,其实包括 forEach、map、filter、find、reduce等等,从中我们可以看出数组在 Javascript 中的地位,同时数组在我们实际的项目中也扮演着重要的地位。如果文章你喜欢,可以继续关注,后面我们还会说到数组的其他一些操作方法也同样有着很重要的作用。

Javascript数组系列三之迭代方法2的更多相关文章

  1. Javascript数组系列二之迭代方法1

    我们在<Javascript数组系列一之栈与队列 >中介绍了一些数组的用法.比如:数组如何表现的和「栈」一样,用什么方法表现的和「队列」一样等等一些方法,因为 Javascript 中的数 ...

  2. JavaScript数组的五个迭代方法的简单实例

    <script> //every() var nums = [1,2,3,4,5]; var result = nums.every(function eve(item,index,arr ...

  3. JavaScript数组的三种定义方法

    数组的定义: <script type="text/javascript"> // <!--声明数组--> // 1.先声明数组长度,后进行赋值 var a ...

  4. Javascript数组系列五之增删改和强大的 splice()

    今天是我们介绍数组系列文章的第五篇,也是我们数组系列的最后一篇文章,只是数据系列的结束,所以大家不用担心,我们会持续的更新干货文章. 生命不息,更新不止! 今天我们就不那么多废话了,直接干货开始. 我 ...

  5. Javascript数组系列四之数组的转换与排序Sort方法

    今天我们继续来介绍 Javascirpt 数组中的方法,也是数组系列的第四篇文章,因为数组的方法众多,每篇文章我们都对数组的每个方法都有比较细致的描述,只要你能够从中成长一点点,那我们的目的就达到了, ...

  6. JavaScript系列--JavaScript数组高阶函数reduce()方法详解及奇淫技巧

    一.前言 reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值. reduce() 可以作为一个高阶函数,用于函数的 compose. reduce()方 ...

  7. Javascript数组的indexOf()、lastIndexOf()方法

    在javascript数组中提供了两个方法来对数组进行查找,这两个方法分别为indexOf(),lastIndexOf(). 这两个方法都有两个参数,第一个参数为需要查找的项,第二个参数则是查找的起始 ...

  8. Javascript数组系列一之栈与队列

    所谓数组(英语:Array),是有序的元素序列. 若将有限个类型相同的变量的集合命名,那么这个名称为数组名. 组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量. ---百度百科 ...

  9. JavaScript数组(三)数组对象使用整理

    一.数组声明方法1. var  a=new Array();2. var a=new Array([size]);3.var a=new Array(['a'],[1],['b'],[123]);4. ...

随机推荐

  1. 【shiro】(5)---基于Shiro的权限管理

    基于Shiro的权限管理项目搭建 前面写了四篇有关权限的文章,算是这篇文章的铺垫了.这篇文章采用 开发环境           JDK1.8          Eclipse          Mav ...

  2. mysql 开发进阶篇系列 52 权限与安全(系统四个权限表的粒度控制关系)

    一.概述 接着上篇的权限介绍,当用户进行连接的时候,权限表的存取过程有以下两个阶段: (1) 先从user表中的host,user, authentication_string 这3个字段中判断连接的 ...

  3. mysql 开发进阶篇系列 20 MySQL Server(innodb_lock_wait_timeout,innodb_support_xa,innodb _log_*)

    1. innodb_lock_wait_timeout mysql 可以自动监测行锁导致的死锁并进行相应的处理,但是对于表锁导致的死锁不能自动监测,所以该参数主要用于,出现类似情况的时候等待指定的时间 ...

  4. Android--通知之Toast

    前言 这篇博客讲解一下Android下的一个简单信息提示的方式:Toast.如果一直看我的博客,会发现在之前的Demo中,一直有用到Toast去提示消息,在这篇博客中就专门讲它.Toast提供一个浮动 ...

  5. MyBatis源码解析(九)——Type类型模块之类型处理器注册器(TypeHandlerRegistry)

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6709157.html 1.回顾 上一篇研究的是类型别名注册器TypeAliasRegist ...

  6. Perl文件名通配和文件查找

    在shell中使用*来对文件名进行通配扩展,在Perl中也同样支持文件名通配.而且perl中的glob通配方式和shell的通配方式完全一致,实际上perl的glob函数就是直接调用csh来通配的(如 ...

  7. LeetCode Animation 题目图解汇总(持续更新中...)

    我会尽力将LeetCode上所有的题目都用动画的形式演示出来,期待与你见证这一天! GitHub Repo:LeetCode Animation Follow: MisterBooo · GitHub ...

  8. [PHP]算法-拼接最小字典序的实现

    拼接最小字典序: 给定一个字符串类型的数组strs,请找到一种拼接顺序,使得将所有字符串拼接起来组成的大字符串是所有可能性中字典顺序最小的并放回这个大字符串. 思路: 1.字典序,12345这五个数, ...

  9. [android] 服务的生命周期(混合方式)

    绑定服务:可以调用服务里面的方法, 如果调用者activity销毁了,服务也会跟着销毁 单独解除绑定的时候,服务也会被销毁 开启服务:不可以调用服务里面的方法 如果调用者activity退出了,服务还 ...

  10. (5)Microsoft office Word 2013版本操作入门_标尺

    1.标尺 :左缩进,右缩进,悬挂缩进,首行缩进,阴影部分 可以左右拖拽调整边缘. 1.1  左缩进:默认缩进所在的段落,要缩进多段则需要多段落选中, 后拖动左缩进. 1.2 首行缩进缩进或者突出所选的 ...