详解JS数组Reduce()方法详解及高级技巧


Posted in Javascript onAugust 18, 2017

基本概念

reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。

reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。

语法:

arr.reduce(callback,[initialValue])
  • callback (执行数组中每个值的函数,包含四个参数)
  • previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
  • currentValue (数组中当前被处理的元素)
  • index (当前元素在数组中的索引)
  • array (调用 reduce 的数组)
  • initialValue (作为第一次调用 callback 的第一个参数。)

简单应用

例1:

var items = [10, 120, 1000];
// our reducer function
var reducer = function add(sumSoFar, item) { return sumSoFar + item; };
// do the job
var total = items.reduce(reducer, 0);
console.log(total); // 1130

可以看出,reduce函数根据初始值0,不断的进行叠加,完成最简单的总和的实现。

reduce函数的返回结果类型和传入的初始值相同,上个实例中初始值为number类型,同理,初始值也可为object类型。

例2:

var items = [10, 120, 1000];
// our reducer function
var reducer = function add(sumSoFar, item) {
 sumSoFar.sum = sumSoFar.sum + item;
 return sumSoFar;
};
// do the job
var total = items.reduce(reducer, {sum: 0});
console.log(total); // {sum:1130}

进阶应用

使用reduce方法可以完成多维度的数据叠加。如上例中的初始值{sum: 0},这仅仅是一个维度的操作,如果涉及到了多个属性的叠加,如{sum: 0,totalInEuros: 0,totalInYen: 0},则需要相应的逻辑进行处理。

在下面的方法中,采用分而治之的方法,即将reduce函数第一个参数callback封装为一个数组,由数组中的每一个函数单独进行叠加并完成reduce操作。所有的一切通过一个manager函数来管理流程和传递初始参数。

var manageReducers = function(reducers) {
 return function(state, item) {
  return Object.keys(reducers).reduce(
   function(nextState, key) {
    reducers[key](state, item);
    return state;
   },
   {}
  );
 }
};

上面就是manager函数的实现,它需要reducers对象作为参数,并返回一个callback类型的函数,作为reduce的第一个参数。在该函数内部,则执行多维的叠加工作(Object.keys())。

通过这种分治的思想,可以完成目标对象多个属性的同时叠加,完整代码如下:

var reducers = { 
 totalInEuros : function(state, item) {
  return state.euros += item.price * 0.897424392;
 },
 totalInYen : function(state, item) {
  return state.yens += item.price * 113.852;
 }
};
var manageReducers = function(reducers) {
 return function(state, item) {
  return Object.keys(reducers).reduce(
   function(nextState, key) {
    reducers[key](state, item);
    return state;
   },
   {}
  );
 }
};
var bigTotalPriceReducer = manageReducers(reducers);
var initialState = {euros:0, yens: 0};
var items = [{price: 10}, {price: 120}, {price: 1000}];
var totals = items.reduce(bigTotalPriceReducer, initialState);
console.log(totals);

在来一个例子:

某同学的期末成绩如下表示

var result = [
  {
    subject: 'math',
    score: 88
  },
  {
    subject: 'chinese',
    score: 95
  },
  {
    subject: 'english',
    score: 80
  }
];

如何求该同学的总成绩?

var sum = result.reduce(function(prev, cur) {
  return cur.score + prev;
}, 0);

假设该同学因为违纪被处罚在总成绩总扣10分,只需要将初始值设置为-10即可。

var sum = result.reduce(function(prev, cur) {
  return cur.score + prev;
}, -10);

我们来给这个例子增加一点难度。假如该同学的总成绩中,各科所占的比重不同,分别为50%,30%,20%,我们应该如何求出最终的权重结果呢?

解决方案如下:

var dis = {
  math: 0.5,
  chinese: 0.3,
  english: 0.2
}
var sum = result.reduce(function(prev, cur) {
  return cur.score + prev;
}, -10);
var qsum = result.reduce(function(prev, cur) {
  return cur.score * dis[cur.subject] + pre;
}, 0)
console.log(sum, qsum);

再看一个例子,如何知道一串字符串中每个字母出现的次数?

var arrString = 'abcdaabc';
arrString.split('').reduce(function(res, cur) {
  res[cur] ? res[cur] ++ : res[cur] = 1
  return res;
}, {})

由于可以通过第二参数设置叠加结果的类型初始值,因此这个时候reduce就不再仅仅只是做一个加法了,我们可以灵活的运用它来进行各种各样的类型转换,比如将数组按照一定规则转换为对象,也可以将一种形式的数组转换为另一种形式的数组,大家可以动手去尝试一样。

[1, 2].reduce(function(res, cur) { 
  res.push(cur + 1); 
  return res; 
}, [])

koa的源码中,有一个only模块,整个模块就一个简单的返回reduce方法操作的对象:

var only = function(obj, keys){
 obj = obj || {};
 if ('string' == typeof keys) keys = keys.split(/ +/);
 return keys.reduce(function(ret, key){
  if (null == obj[key]) return ret;
  ret[key] = obj[key];
  return ret;
 }, {});
};

通过对reduce概念的理解,这个模块主要是想新建并返回一个obj对象中存在的keys的object对象。

var a = {
  env : 'development',
  proxy : false,
  subdomainOffset : 2
}
only(a,['env','proxy'])  // {env:'development',proxy : false}

总结

以上所述是小编给大家介绍的详解JS数组Reduce()方法详解及高级技巧,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
用JS操作FRAME中的IFRAME及其内容的实现代码
Jul 26 Javascript
基于jQuery的树控件实现代码(asp.net+json)
Jul 11 Javascript
js有关元素内容操作小结
Dec 20 Javascript
Javascript代码在页面加载时的执行顺序介绍
May 03 Javascript
jQuery判断iframe中元素是否存在的方法
May 11 Javascript
JS cookie中文乱码解决方法
Jan 28 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
May 16 Javascript
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
Jan 22 Javascript
JS获取字符对应的ASCII码实例
Sep 10 Javascript
彻底搞懂JavaScript中的apply和call方法(必看)
Sep 18 Javascript
vue 查看dist文件里的结构(多种方式)
Jan 17 Javascript
Vue3 响应式侦听与计算的实现
Nov 11 Javascript
javascript将url解析为json格式的两种方法
Aug 18 #Javascript
Vue组件选项props实例详解
Aug 18 #Javascript
浅谈angular4 ng-content 中隐藏的内容
Aug 18 #Javascript
Node.JS更改Windows注册表Regedit的方法小结
Aug 18 #Javascript
浅谈Angular2 ng-content 指令在组件中嵌入内容
Aug 18 #Javascript
Vue中引入样式文件的方法
Aug 18 #Javascript
jQuery+HTML5实现WebGL高性能烟花绽放动画效果【附demo源码下载】
Aug 18 #jQuery
You might like
让PHP以ROOT权限执行系统命令的方法
2011/02/10 PHP
apache中为php 设置虚拟目录
2014/12/17 PHP
php 数组随机取值的简单实例
2016/05/23 PHP
PHP操作MySQL中BLOB字段的方法示例【存储文本与图片】
2017/09/15 PHP
详解PHP发送邮件知识点
2018/05/06 PHP
js动态生成指定行数的表格
2013/07/11 Javascript
JSON与XML优缺点对比分析
2015/07/17 Javascript
jQuery插件DataTable使用方法详解(.Net平台)
2016/12/22 Javascript
ES6新特性六:promise对象实例详解
2017/04/21 Javascript
vue使用v-for实现hover点击效果
2018/09/29 Javascript
vue结合element-ui使用示例
2019/01/24 Javascript
JS中的模糊查询功能
2019/12/08 Javascript
微信小程序swiper实现文字纵向轮播提示效果
2020/01/21 Javascript
Javascript前端下载后台传来的文件流代码实例
2020/08/18 Javascript
[02:51]DOTA2英雄基础教程 风暴之灵
2013/12/23 DOTA
python抓取网页图片示例(python爬虫)
2014/04/27 Python
Python基础之函数用法实例详解
2014/09/10 Python
跟老齐学Python之dict()的操作方法
2014/09/24 Python
Python优先队列实现方法示例
2017/09/21 Python
Python中数组,列表:冒号的灵活用法介绍(np数组,列表倒序)
2018/04/18 Python
Python3基于sax解析xml操作示例
2018/05/22 Python
python实现截取屏幕保存文件,删除N天前截图的例子
2019/08/27 Python
Python爬取破解无线网络wifi密码过程解析
2019/09/17 Python
解决HTML5中的audio在手机端和微信端的不能自动播放问题
2019/11/04 HTML / CSS
Speedo速比涛法国官方网站:泳衣、泳镜、泳帽、泳裤
2019/07/30 全球购物
欧洲著名的二手奢侈品网站:Vestiaire Collective
2020/03/07 全球购物
What is EJB
2016/07/22 面试题
职业生涯规划书的格式
2013/12/29 职场文书
环保倡议书100字
2014/05/15 职场文书
小学生节水倡议书
2015/04/29 职场文书
你为什么是穷人?可能是这5个缺点造成
2019/07/11 职场文书
穷人该怎么创业?谨记以下几点
2019/07/11 职场文书
社交电商模式的兴起:这些新的商机千万别错过
2019/07/26 职场文书
python3.7.2 tkinter entry框限定输入数字的操作
2021/05/22 Python
jackson json序列化实现首字母大写,第二个字母需小写
2021/06/29 Java/Android
一次SQL查询优化原理分析(900W+数据从17s到300ms)
2022/06/10 SQL Server