1.复习数组的方法
需求:拿到数组里的“苏大强”的索引
- 方法一: forEach 弊端:比较消耗性能 它在拿到索引的时候 循环不会停止,return失效 它会把数组里的循环完才结束
const arr =['小红','倪大红','苏大强','苏妲己']
arr.forEach(item,index)=>{
console.log('object') //会打印4次 循环一旦开始,无法在中间被停止
if(item==='苏大强'){
console.log(index)
}
}
- 方法二: some 在找到对应项之后,可以通过return true 固定语法来终止some循环
const arr =['小红','倪大红','苏大强','苏妲己']
arr.some(item,index)=>{
console.log('ok') //会打印3次
if(item==='苏大强'){
console.log(index)
return true
}
}
every 判断里面的每一项是否都满足判断条件,如果每一项都满足返回true,如果只要有一项不满足就返回false
const arr =[
{id:1,name:'苹果',state:true},
{id:2,name:'香蕉',state:true},
{id:3,name:'荔枝',state:true}
]
const result=arr.every(item=>item.state)
console.log(result) //true,只要数组里有一个state是false 结果就返回false
reduce 它是把每次循环的结果累加起来
语法: arr.reduce((累加的结果,当前循环项)=>{ },初始值}) 它也可以没有初始值
arr.reduce( callback, 初始值 )
当没有初始值的时候
/* callback (执行数组中每个值的函数,包含四个参数)
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)initialValue (作为第一次调用 callback 的第一个参数。)
*/
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
})
console.log(arr, sum);
/* 打印的结果是:
1 2 1
3 3 2
6 4 3
[ 1,2,3,4 ] 10
*/
从上面这个例子可以看出 index从1开始的,第一次prev的值是数组的第一个值。数组长度是4,但是reduce循环了3次
看第二个例子:
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
},0) //注意这里设置了初始值
console.log(arr, sum);
/* 打印的结果是:
0 1 0
1 2 1
3 3 2
6 4 3
[ 1,2,3,4 ] 10
*/
上个例子因为传了初始值,所以index是从0开始的,数组的长度是4 reduce循环了4次
结论:如果没有提供初始值,reduce会从索引1的地方开始执行callback方法,跳过数组里的第一个索引,如果提供了初始值initialValue,则索引从0开始
如果是空数组 在没给初始值的时候 会报错,给了初始值就不会报错
var arr = [];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
})//报错,"TypeError: Reduce of empty array with no initial value"
var arr = [];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
}, 0)
console.log(arr, sum); // [ ] 0
const arr =[
{id:1,name:'苹果',state:true,price:30,count:1},
{id:2,name:'香蕉',state:false,price:20,count:3},
{id:3,name:'荔枝',state:true,price:10,count:1}
]
//分析:首先过滤出来选中的项,然后reduce,参数里的amt是每一次累加的结果,
const result=arr.filter(item=>item.state).reduce((amt,item)=>{
return amt +=item.price*item.count //把循环的每一项乘以的结果 累加在amt上 然后return出去 这样第二次循环amt的结果就不再是0了,当循环结束了,没有可以循环的了,reduce会把amt的累加的结果return回来 打印result就是累加的结果
},0)
console.log(result) //最后返回的结果就是amt这个累加的结果
//普通写法
let total=0; //总价
arr.filter(item=>item.state).forEach(item=>{
total+=item.price*item.count
})
console.log(total)
reduce的高级用法
1.计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
2.数组去重
let arr = [1,2,3,4,4,1]let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}},[])
console.log(newArr);// [1, 2, 3, 4]
3.将二维数组转化为一维
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]
4.将多维数组转化为一维数组
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])}console.log(newArr(arr));
//[0, 1, 2, 3, 4, 5, 6, 7]