目录
上一篇跳转链接 : JavaScript_数组常用方法( 1 )
数组常用方法 2 :
方法2 内的数组方法相对复杂一些, 也都 不会改变原始数组 , 都是以 返回值 形式给出结果
1. forEach( )
+ 语法: 数组.forEach( function (item, index, arr) { } )
=> 函数可以接受三个参数
=> 第一个参数: 表示数组内的 每一项 item
=> 第二个参数: 表示数组内每一项的 索引 index
=> 第三个参数: 表示 原始数组 arr
+ 作用: 遍历 数组
+ 返回值: 没有 (undefined)
// 1. forEach()
var arr = [10, 20, 30, 40, 50]
// 0 1 2 3 4
console.log(arr) // [10, 20, 30, 40, 50]
var res = arr.forEach( function a(item, index, arr) {
// 函数 a 会根据 arr 数组中有多少个成员执行多少回
// item, 每一次执行的时候, item 分别是数组内的 每一项
// index, 每一次执行的时候, index 分别是数组内每一项的 索引
// arr, 每一次执行的时候, arr 都代表 原始数组
console.log('我执行了 ', item, ' --- ', index, ' --- ', arr)
} )
forEach 的原理 :
+ 会根据数组内的成员数量分别调用 a 函数
function a(item, index, arr)
+ 第一次调用 a(10, 0, [10, 20, 30, 40, 50])
+ 第二次调用 a(20, 1, [10, 20, 30, 40, 50])
+ 第三次调用 a(30, 2, [10, 20, 30, 40, 50])
+ 第四次调用 a(40, 3, [10, 20, 30, 40, 50])
+ 第五次调用 a(50, 4, [10, 20, 30, 40, 50])
2. map( )
+ 语法: 数组.map( function (item, index, arr) { } )
+ 作用: 映射 数组
=> 对于原始数组里面的数据进行 加工 处理
=> 变成一个 新的数组
+ 返回值: 是一个 新数组
=> 返回值数组和原始数组必然 长度一致 .length ===
=> 新数组内每一个数据都是根据原始数组中每一个数据经过映射加工处理出来的
=> 映射加工处理条件以 return 的形式书写
// 2. map()
var arr = [ 10, 20, 30, 40, 50 ]
console.log('原始数组 : ', arr) // [10, 20, 30, 40, 50]
// 开始映射
var res = arr.map(function a(item, index) {
// 书写加工条件
// 以 return 的形式书写映射条件
return item * (index + 1)
})
console.log('返回值数组 : ', res) // [10, 40, 90, 160, 250]
map 的原理 :
1. 准备一个 新数组
=> [ ]
原始值 => [10, 20, 30, 40, 50]
2. 开始根据原始数据进行遍历
=> 第一次调用 a(10, 0, 原始数组), 返回值是 10, 把这个返回值放在新数组里面
=> 第二次调用 a(20, 1, 原始数组), 返回值是 40, 把这个返回值放在新数组里面
=> 第三次调用 a(30, 2, 原始数组), 返回值是 90, 把这个返回值放在新数组里面
=> 第四次调用 a(40, 3, 原始数组), 返回值是 160, 把这个返回值放在新数组里面
=> 第五次调用 a(50, 4, 原始数组), 返回值是 250, 把这个返回值放在新数组里面
=> ...
3. 把 最终的这个数组 [10, 40, 90, 160, 250] 当做 map 这个方法的返回值
项目实践所用 :
需求背景 : 后端需要一个新的字段 answers , 但其字段跟 options 字段类似 ,
只是 options 字段内的部分数据用不到 , 所以需要对 options 做一下处理 :
原始数据 :
options: [ { itemId: "1", answerScore: 0, label: "数量", value: "1", }, { itemId: "2", answerScore: 0, label: "数量", value: "2", }, { itemId: "3", answerScore: 0, label: "数量", value: "2", }, ];
if (type === "1") { // 题型追加 answers 字段 item.answers = item.options.map((i) => ({ itemId: i.itemId, answerScore: i.answerScore, })); }
answers: [ { itemId: "1", answerScore: 0, }, { itemId: "2", answerScore: 0, }, { itemId: "3", answerScore: 0, }, ];
3. filter( )
+ 语法: 数组.filter( function (item, index, arr) { } )
+ 作用: 过滤 数组 ( 可灵活运用于实现一些 "删除" 功能 )
=> 把原始数组里面 满足条件 的内容拿出来, 组成一个 新的数组
+ 返回值: 是一个 新数组
=> 原始数组内有多少满足条件的(true), 那么新数组里面就有多少个数据
=> 原始数组内没有满足条件的 (false), 那么就是 空的数组
=> 条件以 return 的形式书写
// 3. filter()
var arr = [ 10, 20, 30, 40, 50 ]
console.log('原始数组 : ', arr) // [10, 20, 30, 40, 50]
// 对 arr 进行过滤
var res = arr.filter(function a(item) {
// 书写过滤条件
// 以 return 的形式书写过滤条件
return item / 10 % 2 === 0
// 把每一项满足除以10之后为偶数的数据过滤出来组成一个新数组
})
console.log('返回值数组 : ', res) // [20, 40]
filter 的原理 :
1. 准备一个空数组
=> [ ]
返回值 => [20, 40]
2. 开始根据数组内有多少成员调用多少次 a 函数
=> 第一次调用 a(10, 0, 原始数组), 返回值 false, 那么 10 不加入新数组
=> 第二次调用 a(20, 1, 原始数组), 返回值 true, 那么 20 加入新数组
=> 第三次调用 a(30, 2, 原始数组), 返回值 false, 那么 30 不加入新数组
=> 第四次调用 a(40, 3, 原始数组), 返回值 true, 那么 40 加入新数组
=> 第五次调用 a(50, 4, 原始数组), 返回值 false, 那么 50 不加入新数组
3. 把数组最终结果 [20, 40] 当做 filter 的返回值
项目实践 :
因为其 + 返回值: 是一个 新数组
所以常利用它和 .length 搭配 ( 可节省 计数器 变量的使用了 )
需求 : 题型为必答项 , 并且设置了最少回答数为 mincount
computed: { minAnswer() { let num = this.list.filter((i) => i.value !== ""); return num.length < this.list.mincount; }, },
把原始数组 [ list ] 里面 满足条件 ( value 值 不为空 ) 的内容拿出来 ,组成一个 新的数组 ,
判断其 length 数组长度值 ( 已回答数 ) 小于 定义的最小回答数 时 , 返回 true
提示用户最少回答的警告语 ⚠️
4. find( )
+ 语法: 数组.find( function (item, index, arr) { } )
+ 作用: 查找 数组中满足条件的某一个数据
+ 返回值: 就是数组中你要查找的 满足条件 的这个 数据
+ 查找条件以 return 的形式书写
+ 常用在复杂数据类型的查找
// 4. find()
var arr = [ 100, 200, 301, 400, 500 ]
console.log('原始数组 : ', arr) // [100, 200, 301, 400, 500]
// 我想找到原始数组中的那一个 奇数
var res = arr.find(function (item) {
// 以 return 的形式书写查找条件
return item % 2 === 1
})
console.log('返回值 : ', res) // 301
// find 一般查找的都是复杂数据类型
var arr = [
{ id: 1, name: 'Jack' },
{ id: 2, name: 'Rose' },
{ id: 3, name: 'Tom' }
]
// 我已知的只有 id, 我想知道这个人叫什么
// 使用 find 方法直接找到这个人的完整信息
var res = arr.find(function (item) {
// 条件: 找到 每一项中 id 是 2 的那一个
return item.id === 2
})
console.log('返回值数组 : ', res) // {id: 2, name: "Rose"}
5. every( )
+ 语法: 数组.every( function (item, index, arr) { } )
+ 作用: 判断数组中的 每一个 是否都满足条件
+ 返回值: 是一个 布尔值 Boolean : true / false
=> 如果数组中 每一个 都满足条件, 那么返回值 true
=> 只要数组中 任何一个 不满足条件, 那么返回 false
+ 判断条件以 return 的形式书写
// 5. every()
var arr = [10, 20, 30, 40, 50]
console.log('原始数组 : ', arr) // [10, 20, 30, 40, 50]
var res = arr.every(function (item) {
// 以 return 的形式书写 判断 条件
// 判断数组内是不是所有项都 小于 50
return item < 50
})
console.log('返回值 : ', res) // false
项目实践 :
let count = 0; // 计数器 // 需求 : 题型为必答题 , 统计用户是否每个选项都已回答 this.listData.forEach((item) => { if (item.options.every((i) => i.label !== "")) count++; });
判断数组 [ item.options ] 中的 每一个 label 值 是否都 不为空 , 则 满足条件 ( true )
6. some( )
+ 语法: 数组.some( function (item, index, arr) { } )
+ 作用: 判断数组中是否有某一个满足条件
+ 返回值: 是一个 布尔值 Boolean : true / false
=> 如果数组中有 任何一个 满足条件 , 那么返回 true
=> 只有数组中 所有 都不满足条件的时候 , 才是 false
// 6. some()
var arr = [10, 20, 30, 40, 50]
console.log('原始数组 : ', arr) // [10, 20, 30, 40, 50]
var res = arr.some(function (item) {
// 以 return 的形式书写 判断 条件
// 判断数组内是不是 有某一个 小于 50
return item < 50
})
console.log('返回值 : ', res) // true
项目实践 :
需求 : 题目为必答项,每一项都必须要回答,只要有一项未答则 ⚠️ 提示
computed: { isShow() { return this.list.some((i) => i.value === ""); }, },
判断数组 [ list ] 中是否有 某一个 ( 只要有一个 value 值 为空 ) 则 满足条件,返回 true
7. reduce( )
+ 语法: 数组.reduce( function ( prev, item, index, arr ) { }, 初始值 )
=> 1、参数一 :函数 , 函数根据数组中的成员进行 重复调用
-> 第一个参数 prev : 初始值 或 每一次叠加后的结果
-> 第二个参数 item : 每一项
-> 第三个参数 index : 索引
-> 第四个参数 arr : 原始数组
=> 2、参数二:初始值: 默认是 0 , 表示从什么位置开始叠加
+ 作用: 进行 叠加累计
// 7. reduce( )
var arr = [ 10, 20, 30, 40, 50 ]
console.log('原始数组 : ', arr) // [10, 20, 30, 40, 50]
var res = arr.reduce(function a(prev, item) {
// 以 return 的形式书写每次的叠加条件
return prev + item
}, 0)
console.log('返回值 : ', res) // 150
reduce 原理 :
1. 准备了一个 初始值 , 按照你传递的 第二个参数 来定
=> 准备初始值 var init = 0
=> 第一次赋值 var init = 10
=> 第二次赋值 var init = 30
=> 第三次赋值 var init = 60
=> 第四次赋值 var init = 100
=> 第五次赋值 var init = 150
2. 根据原始数组来调用 a 函数
=> 第一次调用 a(0, 10, 0, 原始数组), return 0 + 10, 把 返回值再次赋值给 init
=> 第二次调用 a(10, 20, 1, 原始数组), return 10 + 20, 把 返回值再次赋值给 init
=> 第三次调用 a(30, 30, 2, 原始数组), return 30 + 30, 把 返回值再次赋值给 init
=> 第四次调用 a(60, 40, 3, 原始数组), return 60 + 40, 把 返回值再次赋值给 init
=> 第五次调用 a(100, 50, 4, 原始数组), return 100 + 50, 把 返回值再次赋值给 init
3. 把最初始准备的变量 init 结果, 当做 reduce 的返回值
ES6新增数组方法(注意浏览器兼容)
includes()
方法 : 用来判断一个数组是否包含一个指定的值 ,如果 是 返回 true ,否则 false 。
语法 :arr.includes(searchElement , fromIndex)
searchElement : 必须 。需要查找的元素值 。
fromIndex :可选 。从该索引处开始查找 searchElement 。
如果为负值 ,则按升序从 array.length + fromIndex 的索引开始搜索 。默认为 0 。
<script>
let arr = ["a","b","c","d"];
let result1 = arr.includes("b");
let result2 = arr.includes("b",2);
let result3 = arr.includes("b",-1);
let result4 = arr.includes("b",-3);
console.log(result1); // true
console.log(result2); // false
console.log(result3); // flase
console.log(result4); // true
</script>
数组 、 字符串 都可以使用 此方法 。
总结
我个人认为 ,
includes
方法好就好在 , 它 返回 的是一个 Boolean 布尔值 ,这样在项目中使用时 , 直接用 if ( 返回的值就可以了 ) ,
相较于
indexOf
方法用起来十分方便 。但各有各的好 ,
indexOf
方法在其他场景比如配合splice
方法删除元素 时就挺好用的 。
图例 :
上一篇跳转链接 : JavaScript_数组常用方法( 1 )