前言
for循环在平时开发中使用频率最高,前后端数据交互时,常见的数据类型就是数组和对象,处理对象和数组时经常使用到 for 遍历,选择合适的数组循环遍历,可以提升开发效率。
常用的for循环为:filter、reduce、every、some、forEach、map
一、filter()方法
filter()过滤方法,会对原数组中的每个元素应用指定的函数,并返回一个新数组,其中包含符合条件的元素。原数组不会受到影响。
1、找出数组中大于10的数据放到新数组中
let arrs = [5, 7, 8, 15, 22, 1, 2]; let newArrs = arrs.filter(item => { return item>10 }) console.log(newArrs); // [15,22]
2、找到数组对象中,年龄小于30岁的数据
let arrs = [{name: "张三", age: 16}, {name: "李四", age: 40}, {name: "王五", age: 28}, {name: "汤姆", age: 20}]; let newArrs = arrs.filter(item => { return item.age<30 }) console.log(newArrs); //[{name: "张三", age: 16}, {name: "王五", age: 28}, {name: "汤姆", age: 20}]
3、数组去重,结合indexOf方法
let arrs = [6, 1, 2, 3, 5, 3, 6]; let newArrs = arrs.filter((item, index, self)=>{ return self.indexOf(item) === index }) console.log(newArrs); // [6, 1, 2, 3, 5]
4、数组对象中过滤掉无用数据
let arrs = [{id: 1, name: "HTML5"}, {id: 2, name: "JavaScript"}, {id: null, name: "小程序"}, {name: "NodeJS"}, {id: 3,name: "VueJS"}]; let newArrs = arrs.filter(item => { return item.id }) console.log(newArrs); // [ {id: 1, name: 'HTML5'}, {id: 2, name: 'JavaScript'}, {id: 3, name: 'VueJS'}]
5、filter和map组合使用,可以使用链式写法;首先去除无用数据,然后给每一条增加一个属性author
let arrs = [{id: 1, name: "HTML5"}, {id: 2, name: "JavaScript"}, {id: null, name: "小程序"}, {name: "NodeJS"}, {id: 3, name: "VueJS"}]; let newArrs = arrs.filter(item => { return item.id }).map(item=>{ return { ...item, author: "siebert" } }) console.log(newArrs); // [{id: 1, name: 'HTML5', author: 'siebert'}, {id: 2, name: 'JavaScript', author: 'siebert'}, {id: 3, name: 'VueJS', author: 'siebert'}]
二、reduce()方法
reduce() 方法对数组中的每个元素按序执行一个指定方法,每一次运行 reducer 会将先前元素的计算结果作为参数传入。
语法
reduce(callbackFn)
reduce(callbackFn, initialValue)
callbackFn参数
prev(必填),上一次调用 callbackFn 的结果。
current(必填),当前元素的值。
index(可选),current 在数组中的索引位置。
array(可选),调用了reduce() 的数组本身。
initialValue
第一次调用回调函数时初始值。如果指定初始值,则callbackFn从数组中的第一个值作为current开始执行;如果没有指定,数组中的第一个值是prev参数的值,数组第二个值是current参数的值;如果数组是空,则抛出错误,所以在不知道数组长度情况下可以指定初始值为0,保持逻辑的严谨性。
1、数组求和 / 求积
let arrs = [1, 2, 3, 4]; let result = arrs.reduce((prev, current, index) => { console.log(prev, current, index); return prev + current; }); console.log("最终结果: " + result); // 1 2 1 // 3 3 2 // 6 4 3 // 最终结果: 10
2.求最大值/最小值
// 求数组中最大值: let arrs = [5, 6, 1, 22, 3, 7]; let result = arrs.reduce((prev, current, index) => { return Math.max(prev, current); }, 0); console.log(result); // 22 //求数组中最小值: let arrs = [5, 6, 1, 22, 3, 7]; let result = arrs.reduce((prev, current, index) => { return Math.min(prev, current); },0); console.log(result); // 0
3、对数组对象处理
// 数组对象求和,求数组对象中age的和: let arrs = [{name: "张三", age: 29}, {name: "李四", age: 16}, {name: "王五", age: 50}, {name: "小明", age: 21}]; let result = arrs.reduce((prev, current, index) => { return prev + current.age }, 0); console.log(result); // 116
三、every()方法
判断数组中所有元素是否满足函数中给定的条件,全部满足返回true,只要有一项不满足则返回false。
1、检查数组中的所有元素是否满足特定条件
let arrs = [1, 2, 3, 4, 5]; let result = arrs.every(num => num > 0); console.log(result); //true
2、检测数组对象中,是否所有商品都有库存
let arrs = [{name: "华为", price: 5899, stock: true}, {name: "苹果", price: 9999, stock: false}, {name: "小米", price: 4399, stock: true}, {name: "红米", price: 899, stock: true}]; let result = arrs.every(item => item.stock); console.log(result); // false
3、检测对象内所有属性是否都有值,配合Object.values()
vue3中定义了一个对象,要判断对象中每个属性是否有值,如果不使用every遍历的话,可能会使用如下方式:
<script setup> import {computed, ref} from "vue"; const obj = ref({ name:"", age:"", gender:"", like:"" }) const state = computed(()=>{ if(obj.value.name && obj.value.age && obj.value.gender && obj.value.like){ return false; } return true; }) function onSubmit(){ console.log("提交表单"); } </script>
计算属性简化一下可以这样写:
const state = computed(() => !(obj.value.name && obj.value.age && obj.value.gender && obj.value.like));
如果使用Object.values()方法,可以将所有的值放入到一个数组中,然后对数组进行every循环遍历,最后得到条件的true或false,计算属性就可以这样做了:
const state = computed(() => { return !Object.values(obj.value).every(item => item) })
简化一下:
const state = computed(() => !Object.values(obj.value).every(item => item));
四、some()方法
1.检查数组中的是否有满足特定条件的元素
let arrs = [55, 26, 3, 12, 39]; let result = arrs.some(item => item<10); console.log(result); // true
2.检查数组对象中,是否有满足price小于1000的元素,并且有stock库存
let arrs = [{name: "华为", price: 5899, stock: true}, {name: "苹果", price: 9999, stock: false}, {name: "小米", price: 4399, stock: true}, {name: "红米", price: 899, stock: true}]; let result = arrs.some(item => item.price < 1000 && item.stock); console.log(result); // true
3.将every示例改造成some方法
// 使用some完成全部对象有值的判断 const state = computed(() => Object.values(obj.value).some(item => !item)); // 只要有一个表单有值就将禁用改可用 const state = computed(() => !Object.values(obj.value).some(item => item));
五、includes()方法
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
注意:includes() 方法只能用于检测基础数据类型(如数字、字符串、布尔值),而不能用于检测包含对象或其他数组的二维数组。如果需要检测对象或其他复杂数据类型,可以使用其他方法或自定义函数来实现。
1、基础用法
const arrs = [1, 2, 3]; console.log(arrs.includes(2)); // true
2、every和includes配合,检测一个数组是否包含另一个数组
let arrs1 = [1, 2, 3, 4, 5, 6, 7]; let arrs2 = [2, 5, 7]; let arrs3 = [1, 6, 9]; let result1 = arrs2.every(item => arrs1.includes(item)); let result2 = arrs3.every(item => arrs1.includes(item)); console.log(result1); console.log(result2); // true // false