zoukankan      html  css  js  c++  java
  • 函数式编程之一柯里化

    什么是柯里化?

    柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数的函数

    下面来看一个案例,两值相加:

    柯里化之前(常见用法)

    function add(x, y) {
        return x + y
    }
    add(1, 2)

    柯里化之后

    function add(x) {
        return function(y) {
            return x + y
        }
    }
    add(1)(2)

    从上面两个例子中似乎好像对柯里化有点感觉了,嗯,再想想

    学习新概念时最怕的就是自己理解错了,这样的体验简直无比糟糕,so我们再来看一个案例

    function multi(a) {
        return function(b) {
            return function(c) {
                return a * b * c;
            }
        }
    }
    multi(1)(2)(3)

    按着对柯里化的理解,我写了这个案例,转念一想,这也是柯里化么? 那么多个return看着有点瘆人,难道是我理解错了么,还是方式用错了,好吧,继续挖掘

    然后找了一个关于柯里化的面试题

    实现一个add方法,使计算结果能够满足如下预期:
    add(1)(2)(3) = 6
    add(1, 2, 3)(4) = 10
    add(1)(2)(3)(4)(5) = 15

    实现方案:

    var addFn = function () {
      var _args = [];
      return function () {
        if (arguments.length === 0) {
          return _args.reduce(function (a, b) {
            return a + b;
          });
        };
        [].push.apply(_args, [].slice.call(arguments));
        return arguments.callee;
      }
    };    
    var sum = addFn();
    sum(1,2,3)(4);  
    console.log(sum());   // 10 

    知识点:

    1。[].slice.call(arguments)

         在ES6以前,我们将一个伪数组转换为真正数组通常情况下都是使用[ ].slice.call()方法

    2。[].push.apply(a, b)

         将b追加到a里面

    运行过程:

    --> [].slice.call(arguments)通过arguments得到一个数组

    --> [].push.apply(_args, [].slice.call(arguments))将数组Push到_args里面

    --> 再次调用时通过闭包保存了上一次返回的值

    --> sum()最后运行时,arguments.length === 0,通过reduce方法求和

     从例子中发现:sum(1,2,3)(4)通过闭包的方式保存了得到的值,不是每次都参与计算得到结果,而是在最后通过sum()才实现求和,以此能看出它的一个特点:延迟计算

    en....貌似要是面试遇到这种题也能写出个答案来了,但是了目前为止我还是无法学以致用,不明白这种函数适用于什么场景

  • 相关阅读:
    [hdu4631 Sad Love Story]最近点对,枚举
    [hdu4629 Burning]三角形面积并,扫描线
    [hdu4628 Pieces]二进制子状态,DP
    [hdu4627 The Unsolvable Problem]数论
    [hdu4622 Reincarnation]后缀数组
    [hdu5379 Mahjong tree]dfs计数
    [hdu5375 Gray code]DP
    决策树
    算法题解之位运算
    算法题解之滑动窗口
  • 原文地址:https://www.cnblogs.com/Tiboo/p/10633469.html
Copyright © 2011-2022 走看看