数组中的各种迭代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…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
