数组中的各种迭代API方法手写
js的数组上有很多实用的方法,不论是在遍历数组上,还是在操作数组内元素上,它有许多不同的遍历数组的方法,同时它还有着可以直接操作数组中间元素的方法。
接下来,我来带大家手写数组里的 遍历方法 。
Array.forEach()
首先, Array.forEach() 接收一个回调作为参数;
同时,在它的回调则接收三个参数,分别代表着(数组项,下标,整个数组本身);
最后,forEach 会把数组进行遍历调用这个传进去的回调函数。
例如:
const singer = [{ name: '周杰伦', num: 20 },{ name: '许嵩', num: 25 },{ name: '林俊杰', num: 19 },{ name: '蔡徐坤', num: 10 },{ name: '鹿晗', num: 0 },
];singer.forEach((item, index, arr) => {console.log(item, index, arr);
})// 输出
// { name: '周杰伦', num: 20 },0, [{ name: '周杰伦', num: 20 },{ name: '许嵩', num: 25 },{ name: '林俊杰', num: 19 },{ name: '蔡徐坤', num: 10 },{ name: '鹿晗', num: 0 }]
// { name: '许嵩', num: 25 },1,[{ name: '周杰伦', num: 20 },{ name: '许嵩', num: 25 },{ name: '林俊杰', num: 19 },{ name: '蔡徐坤', num: 10 },{ name: '鹿晗', num: 0 }]
// ...
// ...
// ...
知道了 Array.forEach() 接收的参数以及怎么执行的,那么我们就可以开始手写它了。
Array.prototype.my_forEach = function(callback) {//将我们手写的方法定义在Array的原型上,接收一个callback回调for (let i = 0; i < this.length; i++) { //遍历这个数组,同时在遍历里面调用这个接收到的回调callback(this[i], i, this)}
}
相对于其它数组遍历方法,forEach方法应该是最简单的一种方法了,没有很特殊的地方,只是简简单单的遍历数组里每一个元素,传递出来。
Array.map()
Array.map() 方法跟 Array.forEach() 方法接收的参数相似;
也是接收一个回调,回调里也是接收那三个参数,分别代表着(数组项,下标,整个数组);
但是它跟 Array.forEach() 还是有一个差别;
那就是它会返回出来一个数组,返回出来的数组的每一项都是回调里面返回出来的值。
例如:
const singer = [{ name: '周杰伦', num: 20 },{ name: '许嵩', num: 25 },{ name: '林俊杰', num: 19 },{ name: '蔡徐坤', num: 10 },{ name: '鹿晗', num: 0 },]const newSinger = singer.map((item, index, arr) => {return item})console.log(newSinger);
打印出来的结果会是:
那么知道了 Array.map() 的特性之后,我们完全可以开始手写它了,
Array.prototype.my_map = function(callback) { // 写一个my_map方法写在Array原型上,接收一个回调const res = []//定义一个数组,用来接收遍历回调得到的新的返回值,最后返回出去for (let i = 0; i < this.length; i++) {res.push(callback(this[i], i, this))//把回调返回出来的值往res数组添加}return res //返回出去数组res
}
Array.map() 相对于普通的遍历来说,它只是会返回出来一个数组,用来接收每个回调的返回值。
Array.filter()
Array.filter() 方法跟 Array.map() 方法接收的参数一样,也是接收一个回调;
回调里同样也是接收那三个参数,分别代表着(数组项,下标,整个数组);
同时它跟 Array.map() 一样,它也会返回出来一个数组;
但是不一样的是,它会对数组每一项进行筛选(故我们通常会叫 filter 叫筛选器方法);
筛选的条件就是回调函数里的 return 所返回出来的条件。
例如:
const singer = [{ name: '周杰伦', num: 20 },{ name: '许嵩', num: 25 },{ name: '林俊杰', num: 19 },{ name: '蔡徐坤', num: 10 },{ name: '鹿晗', num: 0 },]const newSinger = singer.filter((item, index, arr) => {return item.num > 15})console.log(newSinger);//打印结果:// [{ name: '周杰伦', num: 20 },//{ name: '许嵩', num: 25 },//{ name: '林俊杰', num: 19 }]
这里我们用官方的 Array.filter() 方法,在里面返回的条件是 item.num>15 ;
所以我们打印用来接收 filter 返回出来的那个数组,可以看到的是打印的是:
[{ name: '周杰伦', num: 20 }, { name: '许嵩', num: 25 }, { name: '林俊杰', num: 19 }]
打印出来的这个数组里每一个元素都是满足 item.num>15 这个条件的数组项;
所以我们如果想写一个 filter 方法的话,目标就很明确了,我们需要满足:
1.遍历这个数组的同时拿回调函数里返回出来的判断条件来判定数组项是否满足条件2.满足条件的数组项我们就把它放到一个新数组里去,用于最后返回出来那么知道这些,我们就可以很轻松的把这个方法手写出来了:
Array.prototype.my_filter = function(callback) {const res = [];//定义一个空数组,用来装满足判定条件的数组项for (let i = 0; i < this.length; i++) { //遍历回调callback(this[i], i, this) && res.push(this[i]) //语句判断,如果满足回调函数返回出来的判定条件,就把数组该项加入res数组}return res//返回出来满足条件的数组
}
Array.every()
Array.every() 方法与其它数组方法接收的参数也是基本一致,不同的是它是返回出来一个 boolean 值;
应用场景一般是发生在检查所有数组值是否通过测试;
一旦有一个值不通过,那么就会直接返回 false,只有所有值都满足条件,才会返回 true。
根据这些条件我们就可以有了大致方向:
1.对数组每一项进行条件判断,只有一个不满足,直接 return false2.循环结束后加一个 return true 用于返回当所有情况都满足了,那么返回 true```
Array.prototype.my_every = function(callback) {for(let i = 0 ; i < this.length; i++) {if(!callback(this[i],i,this)){//判定不满足的情况return false; //一旦有一个不满足,那么我们就直接返回false,不再执行接下来的代码}}return true;//当所有的元素都不返回false,那么咱们就返回true
}
Array.some()
------------Array.some() 方法跟 Array.every() 方法刚好相反;它也是返回出来一个 boolean 值,不同的是只要有数组里有一个元素满足判定条件,那么就会直接返回 true;若没有一个满足条件,那么就会返回 false。根据这些条件我们就可以往这个方向思考:1.对数组每一项进行条件判断,只有一个满足,直接 return true2.循环结束后加一个 return false 用于返回当所有情况都不满足了,那么返回 false```
Array.prototype.my_every = function(callback) {for(let i = 0 ; i < this.length; i++) {if(callback(this[i],i,this)){//判定满足的情况return true; //一旦有一个满足,那么我们就直接返回true,不再执行接下来的代码}}return false;//当所有的元素都不返回true,那么咱们就返回false
}
Array.reduce()
Array.reduce() 方法应该算是数组的所有的遍历方法里面比较特殊的一个方法吧;
它接收两个参数,第一个参数是需要执行的回调函数,而第二个参数则是初始的一个变量值;
这么说它的第二个参数可能大家都不太理解,没关系,待会儿会带大家仔细讲解。
再讲它的回调函数,它的回调接收四个参数:
function myFunction(pre, value, index, array) {return pre + value;
}
//四个参数分别代表着:
//- 总数(初始值/先前返回的值)
//- 项目值
//- 项目索引
//- 数组本身
那么咱们来看一看官方给出的 Array.reduce() 的实例吧:
let arr = [1,2,3,4,5,6];const res = arr.reduce((pre, value, index, array)=>{console.log(pre,value,index,array);return pre + value
},0)console.log(res);// 运行结果:
// 0 1 0 [ 1, 2, 3, 4, 5, 6 ]
// 1 2 1 [ 1, 2, 3, 4, 5, 6 ]
// 3 3 2 [ 1, 2, 3, 4, 5, 6 ]
// 6 4 3 [ 1, 2, 3, 4, 5, 6 ]
// 10 5 4 [ 1, 2, 3, 4, 5, 6 ]
// 15 6 5 [ 1, 2, 3, 4, 5, 6 ]
// 21
我们可以看到的就是第一次 pre 的值就是我们 reduce 所接收到的第二个参数,而之后的 pre 都是上一次 pre 与 value 的和;
那么为什么是 pre 和 value 的和呢?
原因是每次 reduce 都在执行那个回调,而回填返回出来的值都会传到下一次 reduce 遍历的 pre 中;
这就是 reduce 所接收的各个参数了。
reduce 这个方法多用于数组的累加,累乘等等累积值。
那么如果不给 reduce 传第二个参数会怎样?
这是个好问题,咱们来一起看看:
可以看到的是,它的打印少了一层,那就是第一层,它从数组的第二项开始遍历,而第一个 pre 则是数组没有被遍历的第一项。
所以由此可知,如果我们不给 reduce 传第二个参数,那么它就会默认从数组第二项开始遍历,而第一个 pre 则会变成数组第一项。
那么要手写 reduce 这个方法,我们需要做到哪些条件呢?
1.判断 reduce 是否有接收到第二个参数,做情况判断,决定开始从数组哪个位置开始遍历;2.把每一次回调 return 出来的值都传给下一次回调的 pre ;3.把回调里最后一次 return 传出去。有了这个方向咱们就可以开始手写了:
Array.prototype.my_reduce = function(callback, ...args) {let pre, start = 0;// 定义一个 pre ,方便把最后一次 pre 传出去;if (args.length) {// 判断是否存在第二个参数,决定数组从下标0,还是下标1开始遍历,同时给第一次 pre 赋值pre = args[0]} else {pre = this[0]start = 1}for (let i = start; i < this.length; i++) { // 遍历调用回调,把每一次 pre 传到下一次pre = callback(pre, this[i], i, this)}return pre// 把最后的 pre 传出去}
那么最后的 Array.reduce() 也写完了,数组的遍历方法手写也就到此为止啦。
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享
相关文章:

数组中的各种迭代API方法手写
js的数组上有很多实用的方法,不论是在遍历数组上,还是在操作数组内元素上,它有许多不同的遍历数组的方法,同时它还有着可以直接操作数组中间元素的方法。 接下来,我来带大家手写数组里的 遍历方法 。 Array.forEach(…...

详解量子计算:相位反冲与相位反转
前言 本文需要对量子计算有一定的了解。需要的请翻阅我的量子专栏,这里不再涉及基础知识的科普。 量子相位反冲是什么? 相位反转(phase kickback)是量子计算中的一种现象,通常在量子算法中使用,例如量子…...

C++——C++11第三篇
目录 包装器 function包装器 bind 包装器 function包装器 function包装器 也叫作适配器。C中的function本质是一个类模板,也是一个包装器。 上面的程序验证,我们会发现useF函数模板实例化了三份。 包装器可以很好的解决上面的问题 ,让它只实…...
180 2 22222
选择题(共180题,合计180.0分) 1. 在项目开工会议期间,项目发起人告诉产品负责人和团队项目章程即将完成。然而,由于存在在紧迫的期限内满足政府监管要求的压力,发起人希望立即开始工作。产品负责人下一步应该做什么? A 告诉发起人…...
成人高考初中毕业能报名吗 需要什么条件
初中学历的人员不能直接报名成人高考,考生需要有普通高中,职业高中,中专毕业证等高中同等学力就可以进行报名,在报名期间登陆所在省的教育考试院的成人高考报名入口进行报考。成人高考报名条件是什么1、遵守宪法和法律。2、国家承…...
ChatGPT初体验
ChatGPT初体验 前言 嘿嘿,最近啊AI ChatGPT刷新各大网站,对于我们国人而将很不友好,真的太不友好了。我呢在去年open AI发布的时候就有所关注,那个时候还没有像现在这样火热。谁知道短短几个月便传遍大街小巷。 一、什么是chatG…...
ChatGPT概念狂飙!究竟魅力何在?
原文:http://www.btcwbo.com/6988.html 近期,ChatGPT引领的人工智能概念在资本市场一路狂飙,AIGC题材持续发酵。截至2月7日,Wind ChatGPT指数今年以来累计上涨超50%,汉王科技、海天瑞声、云从科技等概念股股价已经翻倍…...

如何下载阅读Spring源码-全过程详解
这篇文章记录了下载spring源码和在IDEA中打开运行的全过程,并且记录了过程中遇到的问题和解决方案,适合需要学习spring源码的同学阅读。 1.spring源码下载地址 通过Git下载spring-framework项目源码: git clone https://github.com/spring…...

学了两个月的Java,最后自己什么也不会,该怎么办?
学着学着你会发现每天的知识都在更新,也都在遗忘,可能就放弃了。但是只要自己肯练,肯敲代码,学过的知识是很容易就被捡起来的。等你学透了用不了一年也可以学好 Java的运行原理:Java是一门编译解释型语言,…...

前端vue实现获取七天时间和星期几功能
前端vue实现获取七天时间和星期几功能 功能展示代码 <div v-for"(item,index) in same_week" :class"[same_dayitem.date? activ :,dis]" click"select(item)" :keyindex><span>{{item.name}}</span><span>{{item.…...

zookeeper单机部署
一.下载zookeeper压缩包 二.上传解压安装包到/data/zookeeper目录,并解压 tar -zxvf apache-zookeeper-3.5.8-bin.tar.gz 三.修改配置文件 cd apache-zookeeper-3.5.10-bin/conf mv zoo_sample.cfg zoo.cfg vi zoo.cfg 修改为如下: dataDir/data/zooke…...

单片机输入输出模式
单片机输入输出模式输入模式模拟输入、浮空输入、上拉输入、下拉输入GPIO输出模式推挽输出、开漏输出、复用推挽输出、复用开漏输出。上下拉电阻上拉电阻下拉电阻输入模式 模拟输入、浮空输入、上拉输入、下拉输入 模拟输入:I/O端口的模拟信号(电压信号…...

数据结构_ 堆结构与堆排序(c++ 实现 + 完整代码 )
堆结构与堆排序 文章目录堆结构与堆排序引入堆堆结构所满足的数学特性准备代码----------- 往堆中插入元素----------- 删除堆顶堆排序构建完整代码及测试动态分配版本非动态版本引入堆 二叉树 具有左孩子与右孩子的最普通的二叉树。 满二叉树 特殊的二叉树:每个节…...

【MySQL】sql中explain解释和应用
这里写目录标题学习原因MySQL中explain的使用和用法解释explain的使用explain 运行结果的意义文字展示表格展示参考资料:结束语学习原因 在对sql的优化过程中使用了explain对指定的sql进行查看它的运行效果,以便找出sql的性能特点并进行优化 MySQL中ex…...

从零实现深度学习框架:Seq2Seq从理论到实战【实战篇】
来源:投稿 作者:175 编辑:学姐 往期内容: 从零实现深度学习框架1:RNN从理论到实战(理论篇) 从零实现深度学习框架2:RNN从理论到实战(实战篇) 从零实现深度…...

【数据结构入门】-链表之单链表(1)
个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【数据结构初阶(C实现)】 文章标题回顾链表链表的概念及结构各种节点打印链表尾插创建节点尾删头插头删查找在pos…...

Docker竟如此简单!
文章目录什么是容器?容器隔离何为“边界”?容器和虚拟机一样吗?基于 Linux Namespace 隔离机制的弊端容器限制何为“限制”?Cgroups 对资源的限制能力缺陷单进程模型容器镜像容器的诞生容器的一致性何为“层(layer&…...

在外包干了几年,感觉自己都快费了
先说一下自己的情况。大专生,18年通过校招进入湖南某软件公司,干了接近2年的点点点,今年年上旬,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了五年的功能测试…...

Java实现多线程有几种方式(满分回答)
目录JDK8 创建的线程的两种方式orcle文档解释方式一:继承Thread类方式二:实现Runnable接口同时用两种的情况其他间接创建方式Callable接口线程池JDK8 创建的线程的两种方式 orcle文档解释 orcle文档:https://docs.oracle.com/javase/8/docs…...

实例4:树莓派GPIO控制舵机转动
实例4:树莓派GPIO控制舵机转动 实验目的 通过背景知识学习,了解舵机的外观及基本运动方式。了解四足机器人mini pupper腿部单个舵机的组成结构。通过GPIO对舵机进行转动控制,熟悉PWM。了解mini pupper舵机组的整体调零。 实验要求 使用Py…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...

Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
Java中栈的多种实现类详解
Java中栈的多种实现类详解:Stack、LinkedList与ArrayDeque全方位对比 前言一、Stack类——Java最早的栈实现1.1 Stack类简介1.2 常用方法1.3 优缺点分析 二、LinkedList类——灵活的双端链表2.1 LinkedList类简介2.2 常用方法2.3 优缺点分析 三、ArrayDeque类——高…...