map

举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个数组[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map实现如下:

由于map()方法定义在JavaScript的Array中,我们调用Arraymap()方法,传入我们自己的函数,就得到了一个新的Array作为结果:

  1. function pow(x) {
  2. return x * x;
  3. }
  4. var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  5. arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]

map()传入的参数是pow,即函数对象本身。

你可能会想,不需要map(),写一个循环,也可以计算出结果:

  1. var f = function (x) {
  2. return x * x;
  3. };
  4. var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  5. var result = [];
  6. for (var i=0; i<arr.length; i++) {
  7. result.push(f(arr[i]));
  8. }

的确可以,但是,从上面的循环代码,我们无法一眼看明白“把f(x)作用在Array的每一个元素并把结果生成一个新的Array”。

所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把Array的所有数字转为字符串:

  1. var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  2. arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']

只需要一行代码。

reduce

基本概念

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

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

语法:

  1. arr.reduce(callback,[initialValue])
  • callback (执行数组中每个值的函数,包含四个参数)

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

简单应用

例1:

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

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

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

例2:

  1. var items = [10, 120, 1000];
  2. // our reducer function
  3. var reducer = function add(sumSoFar, item) {
  4. sumSoFar.sum = sumSoFar.sum + item;
  5. return sumSoFar;
  6. };
  7. // do the job
  8. var total = items.reduce(reducer, {sum: 0});
  9. console.log(total); // {sum:1130}

进阶应用

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

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

  1. var manageReducers = function(reducers) {
  2. return function(state, item) {
  3. return Object.keys(reducers).reduce(
  4. function(nextState, key) {
  5. reducers[key](state, item);
  6. return state;
  7. },
  8. {}
  9. );
  10. }
  11. };

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

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

  1. var reducers = {
  2. totalInEuros : function(state, item) {
  3. return state.euros += item.price * 0.897424392;
  4. },
  5. totalInYen : function(state, item) {
  6. return state.yens += item.price * 113.852;
  7. }
  8. };
  9.  
  10. var manageReducers = function(reducers) {
  11. return function(state, item) {
  12. return Object.keys(reducers).reduce(
  13. function(nextState, key) {
  14. reducers[key](state, item);
  15. return state;
  16. },
  17. {}
  18. );
  19. }
  20. };
  21.  
  22. var bigTotalPriceReducer = manageReducers(reducers);
  23. var initialState = {euros:0, yens: 0};
  24. var items = [{price: 10}, {price: 120}, {price: 1000}];
  25. var totals = items.reduce(bigTotalPriceReducer, initialState);
  26. console.log(totals);

在来一个例子:
某同学的期末成绩如下表示

  1. var result = [
  2. {
  3. subject: 'math',
  4. score: 88
  5. },
  6. {
  7. subject: 'chinese',
  8. score: 95
  9. },
  10. {
  11. subject: 'english',
  12. score: 80
  13. }
  14. ];

如何求该同学的总成绩?

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

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

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

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

解决方案如下:

  1. var dis = {
  2. math: 0.5,
  3. chinese: 0.3,
  4. english: 0.2
  5. }
  6. var sum = result.reduce(function(prev, cur) {
  7. return cur.score + prev;
  8. }, -10);
  9. var qsum = result.reduce(function(prev, cur) {
  10. return cur.score * dis[cur.subject] + pre;
  11. }, 0)
  12. console.log(sum, qsum);

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

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

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

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

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

  1. var only = function(obj, keys){
  2. obj = obj || {};
  3. if ('string' == typeof keys) keys = keys.split(/ +/);
  4. return keys.reduce(function(ret, key){
  5. if (null == obj[key]) return ret;
  6. ret[key] = obj[key];
  7. return ret;
  8. }, {});
  9. };

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

 
  1. var a = {
  2. env : 'development',
  3. proxy : false,
  4. subdomainOffset : 2
  5. }
  6. only(a,['env','proxy']) // {env:'development',proxy : false}

js高阶函数map和reduce的更多相关文章

  1. JS高阶函数--------map、reduce、filter

    一.filter filter用于对数组进行过滤.它创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素. 注意: filter() 不会对空数组进行检测. 注意: filter() ...

  2. Python高阶函数map、reduce、filter、sorted的应用

    #-*- coding:utf-8 -*- from selenium import webdriver from selenium.webdriver.support.wait import Web ...

  3. 高阶函数map(),filter(),reduce()

    接受函数作为参数,或者把函数作为结果返回的函数是高阶函数,官方叫做 Higher-order functions. map()和filter()是内置函数.在python3中,reduce()已不再是 ...

  4. 高阶函数-map/filter/reduce

    什么样的函数叫高阶函数: 条件:1.函数接受函数作为参数 2.函数的返回值中包含函数 高阶函数之----map函数 map(func, *iterables) --> map objectnum ...

  5. python之高阶函数--map()和reduce()

    以下为学习笔记:来自廖雪峰的官方网站 1.高阶函数:简单来说是一个函数里面嵌入另一个函数 2.python内建的了map()和reduce()函数 map()函数接收两参数,一个是函数,一个是Iter ...

  6. python学习笔记1 -- 函数式编程之高阶函数 map 和reduce

    我用我自己,就是高阶函数,直接表现就是函数可以作为另一个函数的参数,也可以作为返回值 首先一个知识点是 函数的表现形式,印象中的是def  fw(参数)这种方式定义一个函数 python有很多的内置函 ...

  7. [ Python - 9 ] 高阶函数map和reduce连用实例

    1. 利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456: from functools import reduce def str2num( ...

  8. js 高阶函数 map reduce

    map() var arr = [1,3,4]; function a(x){ return x*x; } //map可以将一个函数作为参数执行,将数组中的值,依次使用a函数处理: return ar ...

  9. 高阶函数 map、reduce、filter、sort 函数计算

    map() 循环遍历,返回一个新数组 ,reduce()把结果继续和序列的下一个元素做累积计算 把一个字符串13579先变成Array--[1, 3, 5, 7, 9],再利用reduce()就可以写 ...

随机推荐

  1. ngrep 比 tcpdump 更方便查看的抓包显示工具

    ngrep 是grep(在文本中搜索字符串的工具)的网络版,他力求更多的grep特征,用于搜寻指定的数据包 一: ngrep的安装 CentOS6.2 64位 wget http://nchc.dl. ...

  2. 函数和常用模块【day06】:configparser模块(七)

    本节内容 1.简述 2.配置文件格式 3.创建配置文件 4.读取配置文件 5.增删该查语法 一.简述 在很多情况下,我们都需要修改配置文件,但是,有些配置文件,如mysql数据库的配置文件怎么修改呢? ...

  3. 学习windows编程 day4 之 映射模式

    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRU ...

  4. Code::Blocks代码自动提示设置及常用快捷键

    Code::Blocks代码自动提示设置及常用快捷键(适用windows和linux) 1)以下需要设置的地方均在Settings->Editor...弹出的对话框中. 2)不少命令都可针对当前 ...

  5. OSI七层模型与TCP/IP四层模型

    OSI七层模型与TCP/IP四层模型 OSI模型(Open System Interconnection Reference Model,缩写为OSI),全名“开放式系统互联通信参考模型”,是一个试图 ...

  6. 10 SpringBoot全面接管SpringMVC

    Spring Boot官方文档描述 If you want to keep Spring Boot MVC features and you want to add additional MVC co ...

  7. AsciiMorph - 新奇的 ASCII 字符画生成工具&插件

    AsciiMorph 是一个新奇的 ASCII 字符画生成工具和开源插件.字符画(ASCII Art)的历史可以追溯到几十年前,起初是用在图形显示功能受限的设备上,用ASCII字符集里的可打印字符来拼 ...

  8. Linux之常用命令【service】

    补充说明 service命令 是Redhat Linux兼容的发行版中用来控制系统服务的实用工具,它以启动.停止.重新启动和关闭系统服务,还可以显示所有系统服务的当前状态. 语法 service(选项 ...

  9. luogu P4778 Counting swaps

    计数套路题?但是我连套路都不会,,, 拿到这道题我一脸蒙彼,,,感谢@poorpool 大佬的博客的指点 先将第\(i\)位上的数字\(p_i\)向\(i\)连无向边,然后构成了一个有若干环组成的无向 ...

  10. django学习~models之查询

    一 简介:今天学习models查询的一些东西 二 理解概念 Queryset 定义 从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet 三 细节学习 一 常用的models函数 . ...