for、while、do While、for in、forEach、map、reduce、every、some、filter的使用

for、while、do While、for in、forEach、map、reduce、every、some、filter的使用

for

let arr = [2, 4, 6, 56, 7, 88];//for
for (let i = 0; i < arr.length; i++) {console.log(i + ':' + arr[i]) //0:2 1:4 2:6 3:56 4:7 5:88
}

普通的for循环可以用数组的索引来访问或者修改原来数组对应的元素,即可以改原数组的数据

while

//while
let arr=[1,0,8,7],i=0;
while(i<arr.length){console.log(i+':'+arr[i]);//0:1 1:0 2:8 3:7i++;
}

do while

//do while
let arr=[1,0,8,7],i=0;
do{console.log(i+':'+arr[i]);//0:1 1:0 2:8 3:7i++
}while(i<arr.length)

for in

let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};for(let key in obj){console.log(key+':'+obj[key]) //name:小明 age:18 hobby:run,song,game
}

注意,对象也可以遍历的。

for of

let arr = [2, 4, 6, 56, 7, 88];
let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};
for(let value of arr){console.log(value) //2 4 6 56 7 88
}for (let [key, value] of arr.entries()) {console.log(key+':'+value); //0:2 1:4 2:6 3:56 4:7 5:88
}for (let [key, value] of Object.entries(obj)) {console.log(key+':'+value); //name:小明 age:18 hobby:run,song,game
}

注意:这个for of既可以遍历列表也可以遍历对象。

forEach

最节省内存的一种遍历方式,但是不能用break,也不能用return

let arr = [2, 4, 6, 56, 7, 88];
let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};
arr.forEach((value,key)=>{console.log(key + ':' + value) //0:2 1:4 2:6 3:56 4:7 5:88
})Object.keys(obj).forEach((value)=>{console.log(value) //"name", "age", "hobby"
})

既可以遍历列表也可以遍历对象。

注意:forEach会改变原来数组中的值。

let arr = [{ id: '01001', title: '考研成绩' },{ id: '01002', title: '中国经济复苏进度条' },
]
arr.forEach(function(item,index,arr){item.date = "2023-1-1"
})console.log(arr)

image-20231022181249203

我们改变了原数组,并且,从上面例子可以看出,在js中,可以给一个对象直接添加一个原来没有的属性。

map

同forEach写法一样,循环每一个的时候就相当于在内存中新建了一个数据,比较占内存,与forEach不同的是,它可以return。返回数组。

let arr = [2, 4, 6, 56, 7, 88];
let obj = {name: '小明',age: 18,hobby: 'run,song,game'
};
arr.map((value,index)=>{console.log(index+':'+value) //0:2 1:4 2:6 3:56 4:7 5:88
})Object.values(obj).map((value,key)=>{console.log(key+':'+value) //0:小明 1:18 2:run,song,game
})console.log(Object.keys(obj)) // (3) ["name", "age", "hobby"]
console.log(Object.values(obj)) // (3) ["小明", 18, "run,song,game"]

image-20231022175250501

注意:map方法不会改变原来数组

let arr = [1,2,3,4,5]
let newArr = arr.map(function(item,index,arr){return item*2
})
console.log(arr) // [1,2,3,4,5]
console.log(newArr) // [2,4,6,8,10]

image-20231022181545870

但是对于数组中引用类型中的属性修改,还是会影响原来的数组中对象的属性值的。效果就和forEach一样了。

let arr = [{ id: '01001', title: '考研成绩' },{ id: '01002', title: '中国经济复苏进度条' },
]let newArr = arr.map(function(item,index,arr){item.date = "2023-1-1"return item
})
console.log("arr",arr)
console.log("newArr",newArr)

image-20231022181829867

但是可以用{…item}来做拷贝,然后我们修改拷贝后的值就行了,这样就不会影响原来的数组数据了。

let arr = [{ id: '01001', title: '考研成绩' },{ id: '01002', title: '中国经济复苏进度条' },
]let newArr = arr.map(function(item,index,arr){item = {...item} // 这里我们多了一步拷贝处理item.date = "2023-1-1"return item
})console.log("arr",arr)
console.log("newArr",newArr)

image-20231022182044476

扩展:

js中…的用法

1.什么是…

…是扩展运算符,是es6的新语法

2.怎么使用

作用在对象上,返回一个对象,取出对象所有可遍历属性,返回一个新的对象可以进行拷贝

  1. 基本用法

    let person = { name:'张三',age:18}let someone = {...person}console.log(someone) //返回 { name:'张三',age:18 }
    
  2. 作用于数组对象

    et array = ['a','b','c']let obj = {...array} console.log(obj) // {0:'a',1:'b',2:'c'} 说明:给数组的每个元素生成key,从0开始返回一个新的对象
    
  3. 合并对象

    let name = { name:'张三' }let age = { age:18 }let person = { ...name,...age }console.log(person)  //{name:'张三',age:18}
    
  4. 属性的合并

    let person = {name: "Amy", age: 15};let someone = { ...person, name: "Mike", age: 17};console.log(someone); //{name: "Mike", age: 17} 说明:自定义属性和扩展属性相同的时候,将会被覆盖。如果自定义属性在前,那么扩展属性覆盖自定义属性。反之则是自定义属性覆盖拓展属性。
    

filter

作用:不影响原数组,这个方法会返回一个新数组。回调函数若返回true,filter就会把这一项添加到要返回的新数组中作为一个元素。

注意:传入的函数里必填return,因为会根据return的值为false或true来过滤数据。

filter的几种情况如下:

(1)直接return布尔值,为true则元素值放入数组中,为false的就被过滤掉。

例子1:

let arr = [{ id: '01001', title: '考研成绩', isHot: true },{ id: '01002', title: '中国经济复苏进度条', isHot: false },
]let result = arr.filter((item) => {return item.isHot
})console.log(result) // [{ id: '01001', title: '考研成绩', isHot: true }]// 看打印结果可以发现isHot为false的对象数据就被过滤掉了

例子2:

let arr = [1,2,3,4,5];
let result = arr.filter(function(item, index) {return item>2;
});
console.log(result);
// 输出[ 3, 4, 5 ]
// item:当前元素  index:当前元素的索引值

(2)return非布尔值时,也会通过将数据隐式转化为布尔值来过滤数组。

例子:

let arr = [1,undefined,null,3,0,"",NaN]
let result = arr.filter((item) => {return item
})console.log(result) // [1,3]// 将item的值转化为布尔值后,为false的元素就被过滤掉了,留下的为true的

(3)与其他方法结合使用:

这里先用一个小例子帮大家回忆一下数组的indexOf()方法的用法:用于返回某个指定的值在数组中首次出现的索引值,如果没有找到匹配的元素则返回 -1。

let arr = [1, 2, 3, 4, 5];
let index = arr.indexOf(2);
// 在数组中查找是否有2这个元素
console.log(index) //打印结果是1,表示2和数组中索引为1的元素的值匹配

①与indexOf()方法组合使用进行数组去重:

let arr = [1,1,2,4,5,6,5,5,6]
let newArr = arr.filter((item,index)=>{return arr.indexOf(item) === index// 因为indexOf始终返回第一个符合条件的元素的索引// 数组中重复出现的数值就不可能满足全等判断,就会被过滤掉
})console.log(newArr) // [1,2,4,5,6]

②还有与map方法一起使用:

let arr = [{ id: '01001', title: '考研成绩', isHot: true },{ id: '01002', title: '中国经济复苏进度条', isHot: false },
]// 用map方法给数据加上日期属性let result = arr.map((item) => {item = {...item}item.date = '2023-01-01'return item// map方法后紧接着使用filter方法过滤数据
}).filter((item) => {return item.isHot === true
})console.log(result)

reduce

作用:遍历数组,并构建返回一个最终的值。

语法:array.reduce(function(previous,current,index,arr),initValue);

参数说明:

①不传第二参数initValue时,我们以一个计算数组元素相加之和的例子说明:

let arr = [1,3,5,7]
let result = arr.reduce((previous,current)=>{console.log('previous:',previous, ' current:',current)return previous + current
})console.log('result:',result)

打印结果为:

image-20231022184654345

我们可以看到:

  • 传入的箭头函数执行了数组长度-1次,也就是3次;

  • 回调函数多次调用:

    第一次调用时,previous表示就是数组的第一个元素的值1,current是数组第二个元素的值3;

    第二次调用时,previous表示的是上次调用时return出来的值也就是1+3为4,current是数组第三个元素的值5;

    第三次调用时,previous同样表示的是上次调用返回的值也就是4+5为9,current表示数组第四个元素的值7。

  • result的值就是最后一次计算9+7的结果值16。

②传入第二参数initValue时,我们以一个获得新数组的每个元素是原数组每个元素累计相加之和的例子说明:

let arr = [1,3,5,7]
let sum = 0
let result = arr.reduce((previous,current)=>{console.log(previous, 'current:', current)previous.push(sum + current)sum += currentreturn previous
}, [])console.log('result:', result)

打印结果为:

image-20231022185146784

我们可以看到:

  • 传入的箭头函数执行了arr数组长度一样的次数,也就是4次;
  • previous:箭头函数第一次调用时,表示的是传入的初始值initValue,也就是空数组,后面表示的是上次return出来的值;current:始终表示的是数组arr的每个元素的值;
  • result同样表示最后一次箭头函数调用return返回的结果。

reduce的使用例子:

上面我们举了2个简单例子区分reduce方法传入1个参数和2个参数的区别,下面我以一个计算购物车选中产品数量的例子来说明项目中reduce的具体应用场景。

image-20231022185321361

目前购物车一共有3个产品,其中选中了2种产品,并计算选中的总价为22393,我们可以通过reduce方法计算①②这个2个值。

// arr表示购物车里所有产品数组,其中用不到的数据就省略了
let arr = [{id:12334,isChecked:1, // 1表示购物车选中了这个产品cartPrice:5999, // 表示产品单价5999skuNum:1, // 表示购物车产品数量为1skuName:"小米10 至尊纪念版 双模5G 骁龙865 120W快充 8GB+128GB 陶瓷黑 游戏手机",},{id:12375,isChecked:0, // 0表示购物车没有选中这个产品cartPrice:2323, // 表示产品单价为2323skuNum:1, // 表示购物车产品数量为1skuName:"华为P40 5G全网通智能手机 支持鸿蒙HarmonyOS 零度白 8G+128G",},{id:12376,isChecked:1, // 1表示购物车选中了这个产品cartPrice:8197, // 表示产品单价为8197skuNum:1, // 表示购物车产品数量为1skuName:"Apple iPhone 12 (A2404) 64GB 黑色 支持移动联通电信5G 双卡双待手机",}
]

因为每个产品对象的isChecked属性1就表示选中了,0表示没有选中,因此我们可以通过累计相加这个值来计算购物车选择的产品数:

// 计算购物车选中产品数
let num = arr.reduce((previous,current)=>{return previous + current.isChecked// previous初始值是传入的第二个参数0,current表示数组的当前遍历到的对象
},0)// 通过累计相加所有产品的isChecked的属性值,获得选中的产品数量num为2//计算选中产品总价格,我们也是通过reduce方法累计计算:// 计算购物车选中产品总价格
let price = arr.reduce((previous,current)=>{return previous + current.isChecked * current.cartPrice * current.skuNum// 选中的产品的数量和价格的乘积累计相加},0)// 最终的price的值就是选中产品总价

通过上面的例子我们可以看到这种要累计计算处理数据的情况,使用reduce方法是比较方便的操作。

some和every

因为some()方法和every()方法比较简单,因为比较相似所以这里也是一起讲解。

(1)some()方法用于检测数组中的元素是否满足return的判断条件,如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测;如果没有满足条件的元素,则返回false。

// some方法只要有一个元素符合return的条件就返回true,后面元素就不会再执行判断
let arr = [2,3,4,6]
let result = arr.some((item)=>{return item % 2 === 1 // 判断数组的每个元素是否除以2能余1
})
console.log(result) // 因为第二个元素3符合,所以结果为true

(2)every()方法用于检测数组中的元素是否都满足return的判断条件,只要有一个不符合就会返回false,都符合才返回true。

// every方法要求所有元素符合return的判断条件才返回true,不然就返回false
let arr = [2,3,4,6]
let result = arr.every((item)=>{return item % 2 === 0 // 判断数组的每个元素是否都能被2整除
})
console.log(result) // 因为第二个元素3不符合条件,所以结果为false

总结:

for:简单、可以通过索引访问或者修改原数组

while、do while:循环条件确定,和java一样

for in:可以遍历对象出对象的属性和属性值。

for of:既可以遍历列表也可以遍历对象。可以拿到列表的索引和值,也可以拿到对象的属性和属性值

forEach:省内存,但是不能使用for寻找中的break。可以拿到数组的索引和元素。可以获取对象中的属性值。注意:forEach会改变原来数组中的值。forEach方法没有返回值,一般用于直接修改原数组;

map:不会改变原来数组。但是对于引用数据类型还是会影响原来数组中的对象的属性的。但是可以用过{… 对象}的语法来解决这个问题。map会返回一个数组对象,这个数组对象就是被改变后的对象。

filter:filter()方法用于过滤列表,返回的结果就是过滤后的新数组。这个还是很好用的。

reduce:一般我们用来做累加

some:判断列表中是否有某个元素符合某个规则

every:判断列表中是否全部元素都符合某个规则

注意:js中可以给一个对象直接添加原来没有的属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/736042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录day32 Java版

62.不同路径 public static int uniquePaths(int m, int n) {int[][] dp new int[m][n];//初始化for (int i 0; i < m; i) {dp[i][0] 1;}for (int i 0; i < n; i) {dp[0][i] 1;}for (int i 1; i < m; i) {for (int j 1; j < n; j) {dp[i][j] dp[i-1][j]dp…

Java享元模式源码剖析及使用场景

享元模式 一、介绍二、基本原理三、企业资源管理系统中使用案例三、Java 中的字符串常量池使用了享元模式四、总结优缺点以及使用经验 一、介绍 享元模式是一种结构型设计模式&#xff0c;旨在最大程度地减少内存使用或计算开销。这种模式通过共享对多个类似对象实例所需的状态…

04 数据结构之队列

循环队列 /* squence_queue.h */ #ifndef _SQUENCE_QUEUE_H_ #define _SQUENCE_QUEUE_H_#include <stdio.h> #include <string.h> #include <stdlib.h>#define QUEUE_SIZE 128 #define DEBUG(msg) \printf("--%s--, %s", __func__, msg)typedef i…

SAP BTP Hyperscaler PostgreSQL都有哪些Performance监控 (一)

前言 SAP BTP云平台中&#xff0c;除了自身的HANA数据库作为首选以外&#xff0c;它还支持PostgreSQL的整套服务&#xff0c;并以PaaS的形式提供给客户。你可以按照实例为单位进行购买申请不同标准规格的PG实例&#xff0c;然后构建自己的业务逻辑。Hyperscaler是这套产品或方…

【Python-Docx库】Word与Python的完美结合

今天给大家分享Python处理Word的第三方库&#xff1a;Python-Docx。 什么是Python-Docx&#xff1f; Python-Docx是用于创建和更新Microsoft Word&#xff08;.docx&#xff09;文件的Python库。 日常需要经常处理Word文档&#xff0c;用Python的免费第三方包&#xff1a;Pyt…

【Linux】Shell及Linux权限

Shell Shell的定义 Shell最简单的定义是&#xff1a;命令行解释器。 Shell的主要任务&#xff1a;1. 将使用者的命令翻译给核心进行处理。2.将核心的处理结果翻译给使用者 为什么要有Shell? 使用者和内核的关系就相当于两个完全陌生的外国人之间的关系&#xff0c;他们要进…

springboot、vue、uniapp项目的部署和运行(超链接可直接跳过去)

springboot、vue项目环境配置 1、首先要安装jdk、maven、mysql、nodejs 软件安装 2、安装idea、HbuilderX、navicat 运行项目 3、运行springboot项目、运行vue项目、运行uniapp项目

Dockerfile编写实践篇

Docker通过一种打包和分发的软件&#xff0c;完成传统容器的封装。这个用来充当容器分发角色的组件被称为镜像。Docker镜像是一个容器中运行程序的所有文件的捆绑快照。当使用Docker分发软件&#xff0c;其实就是分发这些镜像&#xff0c;并在接收的机器上创建容器。镜像在Dock…

Linux:线程互斥与同步

目录 线程互斥 锁的初始化 加锁 解锁 锁的初始化 锁的原理 死锁 线程同步 方案一&#xff1a;条件变量 条件变量初始化 等待 唤醒 条件变量的代码示例 基于阻塞队列的生产消费模型 方案二&#xff1a;POSIX信号量 初始化信号量&#xff1a; 销毁信号量 等待信…

JAVA基础-数据结构一(线性表、链表、栈、队列)

一、数组线性表&#xff08;ADT&#xff09; 线性表&#xff1a;又称动态数组&#xff0c;核心是动态数组&#xff0c;可以自行扩容&#xff0c;支持增删改查四种功能 java中有ArrayList也可以自行扩容&#xff0c;二者功能较为相似&#xff0c;且ArrayList也支持转换为数组。 …

中国大学生计算机设计大赛--智慧物流挑战赛基础

文章目录 一、Ubuntu基础1.1 基本操作1.2 文本编辑 二、ROS基础介绍2.1 概念与特点2.2 基本结构2.3 创建工程2.4 节点和节点管理器2.5 启动文件 三、ROS通信机制3.1 话题3.2 服务3.3 动作3.4 参数服务器 四、ROS可视化工具4.1 rviz4.2 rqt4.3 tf 五、Python实现简单的ROS节点程…

01-分析同步通讯/异步通讯的特点及其应用

同步通讯/异步通讯 微服务间通讯有同步和异步两种方式 同步通讯: 类似打电话场景需要实时响应(时效性强可以立即得到结果方便使用),而且通话期间不能响应其他的电话(不支持多线操作)异步通讯: 类似发邮件场景不需要马上回复并且可以多线操作(适合高并发场景)但是时效性弱响应…

MQ高可用相关设置

文章目录 前言MQ如何保证消息不丢失RabbitMQRocketMQKafkaMQ MQ如何保证顺序消息RabbitMQRocketMQKafka MQ刷盘机制/集群同步RabbitMQRocketMQKafka 广播消息&集群消息RabbitMQRocketMQ MQ集群架构RabbitMQRocketMQKafka 消息重试RabbitMQRockeMqKafka 死信队列RocketMQKaf…

Claude3横空出世:颠覆GPT-4,Anthropic与亚马逊云科技共启AI新时代

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

洛谷P3853路标设置

题目背景 B 市和 T 市之间有一条长长的高速公路&#xff0c;这条公路的某些地方设有路标&#xff0c;但是大家都感觉路标设得太少了&#xff0c;相邻两个路标之间往往隔着相当长的一段距离。为了便于研究这个问题&#xff0c;我们把公路上相邻路标的最大距离定义为该公路的“空…

车载电子电器架构 —— 汽车电子电气系统分解

车载电子电器架构 —— 汽车电子电气系统分解 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何…

【JavaWeb】【瑞吉外卖】分页操作数据传输转换

瑞吉day3 搞定了分页以及数据传输的问题 mybatis-plus分页接口实现 分页主要是通过mybatis提供的接口实现的。这篇笔记只是记录如何实现这个接口&#xff0c;并不会深究原理。 博主也比较菜&#xff0c;目前还没有手撕mybatis代码&#xff0c;后续有机会研究一下&#xff08;…

【操作系统概念】第14章:系统保护

文章目录 0. 前言14.1 保护目标14.2 保护原则14.3 保护域14.3.1 域结构14.3.2 实例&#xff1a;UNIX14.3.3 实例&#xff1a;MUTICS 14.4 访问矩阵14.5 访问矩阵的实现14.5.1 全局表14.5.2 对象的访问列表14.5.3 域的能力(权限)列表14.5.4 锁-钥匙机制*14.5.5 比较* 14.6 访问控…

Github 2024-03-10php开源项目日报Top10

根据Github Trendings的统计,今日(2024-03-10统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量PHP项目10Blade项目1Laravel:表达力和优雅的 Web 应用程序框架 创建周期:4631 天开发语言:PHP, BladeStar数量:75969 个Fork数量:24281 次…

网络层学习常见问题及答案整理

问题0&#xff1a;ARP解析协议的定义和特点 ARP&#xff08;地址解析协议&#xff09;高速缓存表用于存储IP地址到MAC地址的映射关系。当一台主机需要将IP数据包发送到同一局域网中的另一台主机时&#xff0c;它需要知道目标主机的MAC地址&#xff0c;以便在以太网帧中使用。AR…