当前位置:首页 > IT科技类资讯

帮你精通JS:函数式编程的七件武器之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的帮精编程基本工作原理如下:

求数列的和

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

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 

 从右往左的折叠

工作原理如下图:

比如 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首先是站群服务器数学上的概念。

从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] 

 【编辑推荐】

Windows10这功能已如同残废!教你如何彻底关闭它 C++和C++程序员谁先完蛋? 2021年值得关注的人工智能趋势 RAID磁盘阵列到底适不适合你?一文读懂 Windows 10是绝唱!微软新系统开始换版本号了

分享到:

滇ICP备2023006006号-16