最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript数组reduce()函数的5个运用场景分享

    正文概述 掘金(codercao)   2021-04-27   511

    作为前端人,我们常常以数组的形式获取某种数据列表,并且需要将其转换为其他形式。在JavaScript中内置在所有数组中有一种非常强大的方法是使用reduce函数。最早提出是在ECMAScript 5.1 ,今年4月份ECMAScript® 2022 中有所定制其使用规范。下面我将介绍它的基本语法和我在使用中实践分享~

    语法

    arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
    

    reducer 函数接收4个参数:Accumulator (acc) (累计器)、Current Value (cur) (当前元素的值)、Current Index (idx) (当前索引)、Source Array (src) (源数组,也就是正在遍历的对象)。

    回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。

    这里要注意的是:

    如果数组为空且没有提供initialValue,会抛出TypeError 。如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行

    Reduce不会直接改变它所调用的对象,但是该对象可以通过调用callbackfn来改变。

    如果你有兴趣深入研究,更多相关资料可以移步到官方规范文档
    它在各大浏览器的兼容性如图~ JavaScript数组reduce()函数的5个运用场景分享

    可能上面的介绍比较枯燥,接下来我们就进行实践分享吧!

    一、计算数组中所有值的总和,或者最值

    // 处理总和的累计器
    const delTotal = (acc, item) => {
      return acc + item;
    };
    
    // 处理最最大值的累计器
    const delMax = (acc, item) => {
      return (acc > item) ? acc : item
    };
    
    const data = [1, 2, 3];
    const total = data.reduce(delTotal);
    const max = data.reduce(delMax);
    
    console.log("The sum is: ", total); //The sum is: 6
    console.log("The max is: ", max); //The max is: 3
    console.log("data: ", data); //data:  [1, 2, 3]
    

    对象数组的操作也是如此,注意如果要处理对象数组,那对象数组中包含的值必须提供初始值,以便各个item正确通过你的函数~

    二、数组去重

    const numberArray = [1,3,4,5,4,5,3,4]
    const stringArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e']
    const delRepetition = (accumulator, currentValue)=> {
      if (accumulator.indexOf(currentValue) === -1) {
        accumulator.push(currentValue)
      }
      return accumulator
    }
    const repNumberArray = numberArray.reduce(delRepetition,[])
    const repStringArray = stringArray.reduce(delRepetition,[])
    
    console.log("The repNumberArray is: ", repNumberArray); //The repNumberArray is: [1, 3, 4, 5]
    console.log("The repStringArray is: ", repStringArray); //The repStringArray is: ["a", "b", "c", "e"]
    
    

    数组去重的方式很多,这种可能不是最佳的,但是也是一种思路。 如果你正在使用一个可以兼容SetArray.from() 的环境, 你可以使用let orderedArray = Array.from(new Set(myArray)); 来获得一个去重的数组~

    三、将二维数组转化为一维

    var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
     ( acc, cur ) => acc.concat(cur),
     []
    );
    console.log("flattened: ", flattened); //flattened: [0, 1, 2, 3, 4, 5]
    
    

    附带挑战:如何使用array.reduce()方法把多维数组转化为一维数组?可以在下面的评论中写下您的解决方案~

    四、计算数组中每个元素出现的次数

    统计出现次数这个场景,也很常见,比如投票统计,下面模拟一个前端框架使用投票统计

    
    
    var initialValue = {};
    
    var reducer = (tally, vote) => {
      if (!tally[vote]) {
        tally[vote] = 1;
      } else {
        tally[vote] = tally[vote] + 1;
      }
    
      return tally;
    };
    
    var votes = [
      "vue",
      "react",
      "angular",
      "vue",
      "react",
      "angular",
      "vue",
      "react",
      "vue"
    ];
    var result = votes.reduce(reducer, initialValue);
    
    // Output
    console.log("Result: ", result)  // Result:  {vue: 4, react: 3, angular: 2}
    console.log("Vue: ", result.vue) // Vue:  4
    console.log("React: ", result.react) // React:  3
    

    类似的,也可以处理按属性对object分类

    五、过滤和映射大数据集,性能更佳

    我们都知道过滤数组,JavaScript提供了一种对数组对象进行过滤的filter()方法,下面我们举个例子,对一个大数据数组(100万个数据)中筛选出所有偶数项,来对比性能

    var bigData = [];
    for (var i = 0; i < 1000000; i++) {
      bigData[i] = i;
    }
    
    let filterBegin = Date.now()
    var filterMappedBigData = bigData.filter(function(value) {
      return value % 2 === 0;
    })
    
    let filterEnd = Date.now()
    let filtertimeSpent = (filterEnd-filterBegin)/1000 + "s";
    
    
    let reducedBegin=Date.now();
    var reducedBigData = bigData.reduce(function(acc, value) {
      if (value % 2 === 0) {
        acc.push(value);
      }
      return acc;
    }, []);
    let reducedEnd = Date.now();
    let reducedtimeSpent = (reducedEnd-reducedBegin)/1000 + " s";
    
    
    console.log("filtered Big Data:", filtertimeSpent)
    console.log("reduced Big Data:", reducedtimeSpent)
    

    在控制台中,我们可以看到filter()花了25毫秒,reduced()花了20毫秒,当然感兴趣的同学,也可以也拿map()做实验,你会发现在处理大数据,reduced()在耗时上都比他们少!

    filtered Big Data: 0.025 s
    reduced Big Data: 0.020 s
    

    如果你对过滤的数据在分别进行操作的话,耗时这块体现的更明显。如果我们要处理大量数据信息,那么了解reduce()函数可以将所有这些操作合并在一起,从而极大地提高性能,这将非常有帮助~

    最后

    本文从语法到实践分享了一些我在实际开发中reduce()函数使用的技巧,希望有点抛砖引玉的作用,当然它还有很多可以结合应用的场景,比如编写函数,检查嵌套对象等等~,也期待评论区你的分享~


    下载网 » JavaScript数组reduce()函数的5个运用场景分享

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元