javascript数组的reduce()与reduceRight()方法

javascript数组的reduce()与reduceRight()方法

reduce()方法

  • 按照数组元素的先后顺序(按索引从小到大的顺序),分别对数组元素执行一次由程序员提供的回调函数(这个回调函数被称作reducer函数);
  • 每一次执行reducer函数时,都会将上一次reducer函数的执行结果作为参数传入;
  • 第一次执行reducer函数时不存在上一次的返回结果;
  • 如果需要reducer函数从索引为0的元素开始执行,则需要传递初始值,否则索引为0的元素将被作为初始值,索引为1的元素作为第一轮执行reducer函数的元素。
  • 如果数组为空且未指定初始值 initialValue,则会抛出 TypeError
  • reduce 不会直接改变调用它的对象,但对象可被调用的 callbackfn 所改变。
  • 遍历的元素范围是在第一次调用 callbackfn 之前确定的。所以即使有元素在调用开始后被追加到数组中,这些元素也不会被 callbackfn 访问。如果数组现有的元素发生了变化,传递给 callbackfn 的值将会是元素被 reduce 访问时的值(即发生变化后的值);
  • 在调用 reduce 开始后,尚未被访问的元素若被删除,则其将不会被 reduce 访问。
  • 如果数组仅有一个元素,并且没有提供初始值 initialValue,或者有提供 initialValue 但是数组为空,那么此唯一值将被返回且 callbackfn 不会被执行。
// 定义一个回调函数以备调用
const getMax=(a, b)=>Math.max(a,b);

// 1.为reduce方法指定初始值时,回调函数从数组索引为0的元素开始调用
[1, 100].reduce(getMax, 50);//100   调用两次
[50].reduce(getMax,10);//50 调用一次

// 2. 没有为reduce方法指定初始值
[1, 100].reduce(getMax);//100   调用一次
[50].reduce(getMax);//50    没有调用    直接返回值
[].reduce(getMax);//TypeError

// 3.为reduce方法指定初始值,但是数组为空数组
[].reduce(getMax,1);//1 没有调用    直接返回值

 

示例一、统计元素出现的次数

说明:写一个函数,接收两个参数,一个是数组,一个是需要统计的元素,需要返回这个元素在数组中出现的次数。

/*
这个例子中需要用num与数组中的所有元素做比较,所以reducer函数要从索引为0的数组元素开始执行;
因此要在第一次执行时要传递初始值。
*/
//
定义数组 let numbers=[1,2,3,4,2,1,3,5,2,5,3,1,3]; //定义函数 function countEle(array, num){ let result=array.reduce(function(pre, cur){ return pre+=cur==num?1:0; }, 0); return console.log(result); } //调用函数 countEle(numbers, 2);

 

示例二、返回数组中的最大值

说明:数组的元素都是数字;定义一个reducer函数并使用它

//定义数组
let arr=[1,45,2,53,654,643,64,345,6453,345];

// 定义reducer函数
//由于只需要比较数组中的所有元素,故不需要为reduce方法传入初始值
function maxNum(pre, cur){
  return pre>cur?pre:cur;  
}

//使用reduce方法调用reducer函数得到最大值
let result=arr.reduce(maxNum);
console.log(result);

 

示例三、获取价格最高的商品

描述:有一组商品的信息的数组,找到产品价格价格最高的那个产品的信息并返回。

// 取价格最高的商品,
let cart = [
    { name: "iphone", price: 12000 },
    { name: "imac", price: 25000 },
    { name: "ipad", price: 3600 }
];

// 定义一个函数,getExpensive(),接收产品信息数组;
//由于需要将所有产品的价格都做比较,所以需要为reduce方法传递初始值。
function getExpensive(array){
    return array.reduce(function(pre,cur){
        return pre=pre.price>cur.price?pre:cur;
    },{});
}
console.log(getExpensive(cart));

 

示例四、计算购物车中商品的总价

描述:有一组商品的信息的数组,找到产品价格价格最高的那个产品的信息并返回。

// 计算购物车中的商品总价
let cart = [
    { name: "iphone", price: 12000 },
    { name: "imac", price: 25000 },
    { name: "ipad", price: 3600 }
];

const total=cart.reduce((total, curr)=>total+=curr.price,0);
console.log(total);//40600

 

示例五、将二维数组转换为一维数组

// 将二维数组转化为一维数组
let flattened=[[0,1],[2,3],[4,5]];

// let result=flattened.reduce(function(pre, cur){
//     return pre.concat(cur);
// },[]);
let result=flattened.reduce((pre,cur)=>pre.concat(cur),[]);
console.log(flattened);
console.log(result);

 

示例六、统计数组中每个元素出现的次数

说明:数组中有相同的元素。

// 计算数组中每个元素出现的次数
let names = ['Alice', 'Tiff', 'Bruce', 'Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
// 思路:需要传入初始值,因为每个数组元素都要统计在内;比较适合以对象的形式存储结果。
let result=names.reduce((pre, cur)=>{
    if(cur in pre){//in运算符:如果指定的属性在指定的对象或其原型链中,则 in 运算符返回 true
        pre[cur]++;
    }else{
        pre[cur]=1;
    }
    return pre;
},{});

console.log(result);

 

示例七、按属性值对object分类

说明:有一些人的信息,按照年龄将这些人分组后存入对象

 

// 按属性值对object分类
// 有个组数,里面存的是多个人的数据,包括姓名和年龄,希望按照年龄大小归类数据
let people=[
    {name:'Alice', age:21},
    {name:'Max', age:20},
    {name:'Jane', age:20},
];

//  定义处理函数
function groupBy(data, property){
    /* 
    思路,使用reduce方法,遍历data中的每一个元素,因此为reduce方法赋初始值为一个对象
    初始值时空对象,对每一个元素使用reducer函数时,先看看对象中有没有与当前元素的property相同的属性
    如果有,则将当前元素push到此属性数组中,如果没有,那么为对象添加此属性并往属性值中push当前元素
    */
    return data.reduce((pre, cur)=>{
        // 每次执行此reducer函数,都要将当前元素中property的值与目标返回对象作比较
        let key=cur[property];
        //假如返回对象中没有当前元素年龄值得属性
        if(!pre[key]){
            pre[key]=[];
        }
        // 这里不是二选一,所以不能用if else.
        pre[key].push(cur);
        return pre;
    },{});

}

// 调用函数并输出结果
console.log(groupBy(people, 'age'));

 

示例八、数组去重

 

posted on 2022-09-26 22:44  前端码牛  阅读(213)  评论(0编辑  收藏  举报

导航