js中的遍历(for、forEach、map、filter、reduce、every、some、includes、find)

js中的遍历


参考: (博主:咸虾米_)各种类型的for循环遍历,forEach/map/filter/for…in/for…of/every/some/includes/reduce的详细用法

1. for 和 forEach

性能上的比较:for性能更优

let arrs = [...Array(9999999).keys()]
let total = 0;
let startTime = Date.now();

// for:
// 支持break跳出整个循环
// 支持continue跳出当前,继续余下循环操作
for(let i=0; i<arrs.length; i++) {
  total+=i;
}
let endTime = Date.now();
let countTime = endTime - startTime;
console.log("for:计数---->"+total); // for:计数---->49999985000001
console.log("for:消耗时间---->"+countTime); // 129

total = 0;
startTime = Date.now();
// forEach:
// 不支持break和continue
// 支持return结束当前,继续余下循环操作
arrs.forEach(item=>{
	total+=item;
})
endTime = Date.now();
countTime = endTime - startTime;
console.log("forEach:计数---->"+total); // forEach:计数---->49999985000001
console.log("forEach:消耗时间---->"+countTime); // forEach:消耗时间---->267
  • for循环直接操作索引,没有额外的函数调用和上下文,所以性能是最快的
  • for可以使用break终止,forEach不支持跳出循环
  • forEach可以使用return,满足条件使用return可以结束当前这次循环,但是剩下的循环还是继续跑完,但有forEach内加不加return其实消耗的时间都是差不多相同的

异步同步化的支持度:for支持,forEach不支持

async function fetchData_for() {
	let arrs = [1, 2, 3];
  let datas = [];
  // for:支持异步等待
  for (let i = 0; i < arrs.length; i++) {
		const { data } = await getData({
			url:"http://jsonplaceholder.typicode.com/posts/" + arrs[i]
		});
		datas.push(data);
	}
  console.log(datas); // (3) [{…}, {…}, {…}]
}
fetchData_for();

function fetchData_forEach() {
	let arrs = [1, 2, 3];
  let datas = [];
  // forEach:不支持异步等待
  arrs.forEach(async item=>{
    const { data } = await getData({
      url:"http://jsonplaceholder.typicode.com/posts/" + item
    })
    datas.push(data)
  })
  console.log(datas); // []
}
fetchData_forEach();

2. map

map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

用法1:将数组内每个元素×2后,获取新数组

let arrs = [1,2,3,4];
let newArrs = arrs.map((element, index, array) => {
  // 参数1 element:数组中当前正在处理的元素。
  // 参数2 index:正在处理的元素在数组中的索引。
  // 参数3 array:调用了 map() 的数组本身。
  return element * 2;
});
console.log(newArrs); // [2, 4, 6, 8]

用法2:将数组对象内每个元素的名称拿出来,作为一个新数组

let peopleList = [
  {
    name: '张三',
    age: 18,
  },
  {
    name: '李四',
    age: 19,
  },
  {
    name: '王五',
    age: 20,
  },
];
let names = peopleList.map(item => item.name);
console.log(names); // ['张三', '李四', '王五']

用法3:修改元数组对象,生成新数组

let peopleList = [
  {
    name: '张三',
    age: 18,
  },
  {
    name: '李四',
    age: 19,
  },
  {
    name: '王五',
    age: 20,
  },
];
let newPeopleList = peopleList.map(item => {
  return {
    ...item,
    age: item.age + '岁',
    intro: '我的名字叫' + item.name,
  }
})
// let newPeopleList = peopleList.map(item=>({...item, age: item.age + "岁", intro: '我的名字叫' + item.name})); // 一行简写
console.log(newPeopleList);
// [
//     {
//         "name": "张三",
//         "age": "18岁",
//         "intro": "我的名字叫张三"
//     },
//     {
//         "name": "李四",
//         "age": "19岁",
//         "intro": "我的名字叫李四"
//     },
//     {
//         "name": "王五",
//         "age": "20岁",
//         "intro": "我的名字叫王五"
//     }
// ]

用法4:将原数组中属性进行更换,配合对象解构,可以更直观

let arr = [{key:0,content:"篮球"},{key:1,content:"足球"},{key:2,content:"排球"}];
let newArr = arr.map(({key,content})=>({value:key,text:content}));
console.log(newArr); // [{value: 0, text: '篮球'},{value: 1, text: '足球'},{value: 2, text: '排球'}]

用法5:将异步请求map到新数组中,使用Promise.all同事处理多个Promise

let arr = [1, 2, 3];
const promises = arr.map(async (num) => {
  const result = await getData({
    url:"http://jsonplaceholder.typicode.com/posts/" + num
  })
  return result;
});
console.log(promises); // [Promise, Promise, Promise]
Promise.all(promises).then(res => {
	console.log(res); // (3) [{…}, {…}, {…}]
})

3. filter

filter() 方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。filter()过滤方法,会对原数组中的每个元素应用指定的函数,并返回一个新数组,其中包含符合条件的元素。原数组不会受到影响。

用法1:过滤出数值数组中的偶数

let arrs = [5,7,8,15,22,1,2];
let newArrs = arrs.filter((item, index, array) => {
  // 参数1:数组中当前正在处理的元素。
  // 参数2:正在处理的元素在数组中的索引。
  // 参数3: 调用了 filter() 的数组本身
  console.log(item, index, array);
	return item % 2 === 0;
})
console.log(newArrs); // [8, 22, 2]

用法2:数组去重,结合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]

用法3:数组对象中过滤掉无用数据

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"}]

用法4:filter和map用链式写法组合使用

let arrs = ['6','1','2','3','5','3','6'];
let newArrs = arrs.filter((item,index,self) => {
	return self.indexOf(item) === index
}).map(Number) // 字符串转数值型
console.log(newArrs); // [6, 1, 2, 3, 5]

4. reduce

reduce() 方法对数组中的每个元素按序执行一个提供的 reduce 函数,每一次运行 reduce 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

用法1:求和/求积

let arr = [1, 2, 3, 4];
let result = arr.reduce((prev, current, index, array) => {
  // 参数1:上一次调用callbackFn的结果(必须)
  // 参数2:当前元素的值(必须)
  // 参数3:currentValue在数组中的索引
  // 参数4:调用了reduce()的数组本身
  return prev + current;
}, 0) // 这里的0为初始值 当有初始值时,循环从arr[0]开始,第一个循环的prev即为该初始值
// 当没有初始值参数时,循环从arr[1]开始,第一个循环的prev及为a[0]
// 当不知道数组内是不有值时,进行reduce操作最好加上初始值参数,防止程序报错
console.log(result); // 10
let result2 = arr.reduce((prev, current, index, array) =>{
  return prev * current;
})
console.log(result2); // 24

用法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 result2 = arrs.reduce((prev, current, index) => {
  return Math.min(prev, current);
}, 0)
console.log(result2); // 0

用法3:对数组对象处理

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

5. every

every() 方法测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值,全部满足返回true,只要有一项不满足则返回false。

用法1:检查数组中的所有元素是否满足特定条件

let arr1 = [2, 4, 6, 8];
let arr2 = [1, 2, 4, 6, 8];
let result1 = arr1.every((item, index, array) => {
  // 参数1:数组中当前正在处理的元素。
  // 参数2:正在处理的元素在数组中的索引。
  // 参数3:调用了 every() 的数组本身。
  console.log(item, index, array);
  return item % 2 === 0;
});
let result2 = arr2.every(item => item % 2 === 0);
console.log(result1); // true
console.log(result2); // false

用法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()(用于检查表单是否都填写)

let obj1 = {
  name: 'name',
  title: 'title',
}
let obj2 = {
  name: 'name',
  title: '',
}
let result1 = Object.values(obj1).every(item => item);
let result2 = Object.values(obj2).every(item => item);
console.log(result1, result2); // true false

6. some

some() 方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到一个元素使得提供的函数返回 true,则返回 true;否则返回 false。它不会修改数组。只要找到满足的就不再往下遍历

用法1:检查数组中的是否有满足特定条件的元素

let arrs = [55, 26, 3, 12, 39];
let result = arrs.some((item, index, array) => {
  // 参数1:数组中当前正在处理的元素。
  // 参数2:正在处理的元素在数组中的索引。
  // 参数3:调用了 some() 的数组本身。
  console.log(item, index, array);
  // 找到满足条件就不再往下遍历
  // 55 0 [55, 26, 3, 12, 39]
  // 26 1 [55, 26, 3, 12, 39]
  return item % 2 === 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.some(item => item.price < 1000 && item.stock);
console.log(result); // true

用法3:检测对象内是否存在有值的属性,配合Object.values()(用于检查表单)

let obj1 = {
  name: '',
  title: 'title',
}
let obj2 = {
  name: '',
  title: '',
}
let result1 = Object.values(obj1).some(item => item);
let result2 = Object.values(obj2).some(item => item);
console.log(result1, result2); // true false

some 和 evey 的对比

  • some() 只要有一个遍历项满足条件就返回true
  • evey()所有遍历项都满足条件才返回true

7. includes

includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。

用法1:基础用法,检查数组中是否含有指定值

// 参数1:需要查找的值。
// 参数2:开始搜索的索引(从零开始),会转换为整数。
let arr = [1, 2, 3, 4, 5];
console.log(arr.includes(2)); // true
console.log(arr.includes(2, 2)); // false

用法2:every和includes配合,检测一个数组是否包含另一个数组

let arrs1 = [1, 2, 3, 4, 5, 6, 7];
let arrs2 = [1, 2, 3];
let arrs3 = [0, 2, 3];
let result1 = arrs2.every(item => arrs1.includes(item));
let result2 = arrs3.every(item => arrs1.includes(item));
console.log(result1, result2); // true false

8. find

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。只要找到满足的就不再往下遍历

用法1:找到数值中满足条件的第一个元素

let arrs = [55, 26, 3, 12, 39];
let result = arrs.find((item, index, array) => {
  // 参数1:数组中当前正在处理的元素。
  // 参数2:正在处理的元素在数组中的索引。
  // 参数3:调用了 find() 的数组本身。
  console.log(item, index, array);
  // 找到满足条件就不再往下遍历
  // 55 0 [55, 26, 3, 12, 39]
  // 26 1 [55, 26, 3, 12, 39]
  return item % 2 === 0;
});
console.log(result); // 26

用法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.find(item => item.price < 1000 && item.stock);
console.log(result); // {name: '红米', price: 899, stock: true}

find 和 some的对比

返回值不同:

  • find返回找到的满足条件的数组元素
  • some返回布尔值,表示是否存在满足条件的数组元素
  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScriptMap对象是一种以键值对的形式存储数据的集合对象。通常我们使用Map对象来存储和访问数据。 遍历Map对象的方式之一是使用forEach()方法。 forEach()方法是一个数组和Map对象的方法,用于循环访问数组或Map对象的元素,并对每个元素执行指定的操作。它最常用的形式是接受一个回调函数作为参数。 在遍历Map对象时,forEach()方法接受一个回调函数作为参数,其回调函数包含三个参数:当前元素的值、当前元素的键和Map对象本身。我们可以根据需要使用这些参数执行任何操作。例如,我们可以调用map对象的get()方法来获取当前元素的值,然后将结果输出到控制台。 下面是一个简单的示例,演示如何使用forEach()方法遍历Map对象: ``` //创建一个新的Map对象 var myMap = new Map([ ["key1","value1"], ["key2","value2"] ]); //使用forEach()方法遍历Map对象 myMap.forEach(function(value, key, myMap) { console.log(key + " = " + value); }); ``` 在上面的代码,我们首先创建了一个名为myMap的新Map对象。然后,我们使用forEach方法在控制台上打印了每个键值对。在回调函数,我们使用value和key参数来访问当前元素的值和键,并将它们输出到控制台。 总而言之,JavaScriptforEach()方法提供了一种简单的方式来遍历Map对象,可以使用回调函数来执行任何需要执行的操作,包括访问元素的键值对、调用Map对象的方法等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值