Javascript入门到精通:函数式编程的七件武器之Reduce与Map
小职 2021-03-10 来源 : 阅读 1092 评论 0

摘要:本文主要介绍了Javascript入门到精通:函数式编程的七件武器之Reduce与Map,通过具体的内容向大家展现,希望对大家Javascript的学习有所帮助。

本文主要介绍了Javascript入门到精通:函数式编程的七件武器之Reduce与Map,通过具体的内容向大家展现,希望对大家Javascript的学习有所帮助。

Javascript入门到精通:函数式编程的七件武器之Reduce与Map

JavaScript是当今流行语言中对函数式编程支持最好的编程语言。函数式编程的七个函数分别为:

 

- reduce() and reduceRight() to apply an operation to a whole array, reducing it to a single result

- map() to transform one array into another by applying a function to each of its elements

- flat() to make a single array out of an array of arrays

- flatMap() to mix together mapping and flattening

- forEach() to simplify writing loops by abstracting the necessary looping code

以及 search 与 selection 的函数:

 

- filter() to pick some elements from an array

- find() and findIndex() to search for elements that satisfy a condition

- A pair of predicates, every() and some(), to check an array for a Boolean test

一、array.reduce() 将数列降维至一个值

 

当我们处理array的时候,总是陷入到无穷尽的loop循环之中,掉入进琐碎的陷阱,戕害我们的思维和大脑。

 

reduce的基本工作原理如下:

 Javascript入门到精通:函数式编程的七件武器之Reduce与Map

 

求数列的和

 

首先从耳熟能详的求数列之和起步。

 

const myArray = [22, 9, 60, 12, 4, 56];

const sum = (x, y) => x + y;

const mySum = myArray.reduce(sum, 0); // 163

观察其运行轨迹:

 

#+begin_src js :results output

const myArray = [22, 9, 60, 12, 4, 56];

const sumAndLog = (x, y) => {

 console.log(`${x}+${y}=${x + y}`);

  return x + y;

};

myArray.reduce(sumAndLog, 0);

 

#+end_src

 

#+RESULTS:

: 0+22=22

: 22+9=31

: 31+60=91

: 91+12=103

: 103+4=107

: 107+56=163

求均值

 

有了reduce,我们得以用“描述”的方式,以decalratively的方式求得average:

 

const average = arr => arr.reduce(sum, 0) / arr.length;

console.log(average(myArray)); // 27.166667

求均值的第二种方法,将length写到里面:

 

const average2 = (sum, val, ind, arr) => {

  sum += val;

  return ind === arr.length - 1 ? sum / arr.length

         : sum; //将这作为思考的原材料

};

 

console.log(myArray.reduce(average2, 0)); // 27.166667s

更近一步,将average作为固有属性:

 

Array.prototype.average = function() {

  return this.reduce((x, y) => x + y, 0) / this.length;

};

 

let myAvg = [22, 9, 60, 12, 4, 56].average(); // 27.166667

单词计算多个值

 

虽然 reduce 只能返回单个结果,但是此返回结果却可以包含多个元素,比如是object。

 

const average3 = arr => {

  const sumCount = arr.reduce(

    (accum, value) => ({sum: value + accum.sum, count: accum.count + 1}),

    {sum: 0, count: 0}

  );

 

  return sumCount.sum / sumCount.count;

};

 

console.log(average3([7, 11, 19, 23]));

以array的方式改写:

 

const average4 = arr => {

  const sumCount = arr.reduce(

    (accum, value) => [accum[0] + value, xaccum[1] + 1],

    [0, 0]

  );

  return sumCount[0] / sumCount[1];

};

 

console.log(average4(myArray)); // 27.166667

从右往左的折叠

 

工作原理如下图:

 Javascript入门到精通:函数式编程的七件武器之Reduce与Map

 

比如 reverse 字符串的常规解决方案为:

 

const reverseString = str => {

  let arr = str.split("");

  arr.reverse();

  return arr.join("");

};

 

console.log(reverseString("MONTEVIDEO"));  // OEDIVETNOM

而reduceRight的解题方案呢,

 

const reverseString2 = str =>

  str.split("").reduceRight((x, y) => x + y, "");

 

console.log(reverseString2("OEDIVETNOM"));  // MONTEVID

二、array.map 从数学到编程

 

map首先是数学上的概念。

 Javascript入门到精通:函数式编程的七件武器之Reduce与Map

 

从object中提取数据

 

const markers = [

  {name: "AR", lat: -34.6, lon: -58.4},

  {name: "BO", lat: -16.5, lon: -68.1},

  {name: "BR", lat: -15.8, lon: -47.9},

  {name: "CL", lat: -33.4, lon: -70.7},

  {name: "CO", lat:   4.6, lon: -74.0},

  {name: "EC", lat:  -0.3, lon: -78.6},

  {name: "PE", lat: -12.0, lon: -77.0},

  {name: "PY", lat: -25.2, lon: -57.5},

  {name: "UY", lat: -34.9, lon: -56.2},

  {name: "VE", lat:  10.5, lon: -66.9},

];

 

let averageLat = average(markers.map(x => x.lat)); // -15.76

let averageLon = average(markers.map(x => x.lon)); // -65.53

// extended array.prototype

let averageLat2 = markers.map(x => x.lat).average();

let averageLon2 = markers.map(x => x.lon).average();

悄无声息的处理数据

 

看一个我们想当然的应用:

 

["123.45", "67.8", "90"].map(parseFloat);

// [123.45, 67.8, 90]

 

["123.45", "-67.8", "90"].map(parseInt);

// [123, NaN, NaN]

这是因为 parseInt 有一个 optional 的参数 radix。

 

数列的表示方法

 

现在我们来创建一个 range.

 

const range = (start, stop) =>

  new Array(stop - start).fill(0).map((v, i) => start + i);

// 必须写一个v,也必须写 new

let from2To6 = range(2, 7); // [2, 3, 4, 5, 6]

尝试求乘方:

 

const range = (start, stop) =>

  new Array(stop - start).fill(0).map((v, i) => start + i);

 

const factorialByRange = n => range(1, n + 1).reduce((x, y) => x * y, 1);

 

factorialByRange(5); // 120

factorialByRange(3);

尝试字母表:

 

const ALPHABET = range("A".charCodeAt(), "Z".charCodeAt() + 1).map(x =>

  String.fromCharCode(x)

);

 

// ["A", "B", "C", ... "X", "Y", "Z"]

用 reduce 构造 map

 

reduce是所有其他函数的起点,

 

const myMap = (arr, fn) => arr.reduce((x, y) => x.concat(fn(y)), []);

尝试两种不同的解决方案:

 

const myArray = [22, 9, 60, 12, 4, 56];

const dup = x => 2 * x;

 

console.log(myArray.map(dup));    // [44, 18, 120, 24, 8, 112]

console.log(myMap(myArray, dup)); // [44, 18, 120, 24, 8, 112]

console.log(myArray);             // [22, 9, 60, 12, 4, 56] 


我是小职,记得找我

✅ 解锁高薪工作

✅ 免费获取学习教程,开发工具,代码大全,参考书籍

Javascript入门到精通:函数式编程的七件武器之Reduce与Map

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved