Javascript函数式编程测验

时间:2014-03-12 16:53:20

标签: javascript functional-programming

这是问题所在。我必须实现 make 功能:

var sum = function (a, b) { return a + b; }
var mult = function (a, b) { return a * b; }

//'make' function goes here

var res = make(1)(2)(3)(4);

console.log(res(sum));    //OUTPUT: 10
console.log(res(mult));   //OUTPUT: 24

我已经实现了它,但我觉得还有一种更好的方式。 :)

所以,这是我的解决方案:

function make(a, arr) {
    if (a instanceof Function) { return arr.reduce(a); }

    arr = arr || [];
    arr.push(a);

    return function (b) { return make(b, arr); };
}

4 个答案:

答案 0 :(得分:3)

你想要功能吗?你可以有功能!

function sum(a, b) { return a + b; }
function mult(a, b) { return a * b; }
function diff(a, b) { return a - b; }

function make(x, f) {
    if (typeof x === 'function') return f(x);
    return function(y) { 
        return make(y, function(a) { 
            return f ? a(f(a), x) : x; 
        });
    };
}

console.log(make(1)(2)(3)(4)(sum));   // -> 10
console.log(make(1)(2)(3)(4)(mult));  // -> 24
console.log(make(4)(3)(2)(1)(diff));  // -> -2

不是构建一个数组,而是建立一个函数,当给定一个函数时,从左到右减少使用该函数的所有元素:)

我很确定这不符合任何人希望在其代码库中看到的代码。

答案 1 :(得分:0)

function make(inp, arr) {
  if (typeof inp == 'function') {
    while(arr.length > 1)
      arr.push(inp(arr.pop(), arr.pop()));
    return arr[0];
  }

  if (!arr) arr = [];
  arr.push(inp);
  return function (inp1) {
    return make(inp1, arr);
  };
}

答案 2 :(得分:0)

试试这个

function make(x) {
    return function (y) {
        if (y instanceof Function)  return Array.prototype.reduce.call(x, y);

        var pars = Array.prototype.concat(x, y);
        return make(pars);
    };
}

答案 3 :(得分:0)

这是一个更好的JavaScript特定解决方案:



var test = make(1)(2)(3)(4);

alert(test(add)); // ((1 + 2) + 3) + 4 = 10
alert(test(mul)); // ((1 * 2) * 3) * 4 = 24
alert(test(sub)); // ((1 - 2) - 3) - 4 = -8

function make(x) {
    if (typeof x !== "function") return foldl([x]);
    throw new TypeError("Initial value can't be a function");
}

function foldl(array) {
    return function (fx) {
        return typeof fx !== "function" ?
            foldl(array.concat(fx)) :
            array.reduce(fx);
    };
}

function add(a, b) { return a + b; }
function mul(a, b) { return a * b; }
function sub(a, b) { return a - b; }




这种方法有几个优点:

  1. 在编写make(add)等错误代码时,可以更好地报告错误。
  2. 简单的功能定义,易于阅读和理解。
  3. 如果您需要foldr,请将reduce重命名为reduceRight
  4. 使用concat代替push保留原始数组。
  5. 我无法想到make的更好的功能实现。