Javascript:编写一个函数,并为每个组合提供参数放置说明

Javascript: Compose a function with argument placement instructions for each composition

本文关键字:组合 说明 参数 函数 一个 Javascript      更新时间:2023-09-26

我正在寻找一个javascript函数,可以:

条件(I)

在定义中没有递归时组成另一个函数,有点像在数学中,当函数被赋予幂时,但在第一个输入中可能有多个参数-例如使用(数学)函数f:


f(x):= x+2

f <一口> 5>

条件(II)

或者或者甚至在组合的每一步中输入自定义参数:


(5 <一口> 2> <一口> 2 )<一口><一口><一口> 2 =

Math.pow(Math.pow(Math.pow(5,2),2),2) = Math.pow.pow([5,2],2,["r",2]])
//first arg set, how times the next, 2nd arg set - "r" stands for recursion - 
//that argument will be occupied by the same function
//Using new solution: 
_.supercompose(Math.pow,[[5,2],[_,2],[_,2]]) //-> 390625

2 <一口>((5 <一口> 2> <一口> 3 ) =

Math.pow(2,Math.pow(Math.pow(5,2),3)) = Math.pow.pow([5,2],["r",2],["r",3],[2,"r"])
//Using new solution:
_.supercompose(Math.pow,[[5,2],[_,2],[_,3]]) //-> 244140625
_.supercompose(Math.pow,[[5,2],[_,2],[_,3],[2,_]]) //-> Infinity (bigger than the max. number)

注意:以上只是模板,生成的函数不一定要有确切的参数,但越接近这个(或创造性的,例如,分支的可能性像这样->[2,4,"r",4,2,"r"],这也会很复杂)越好。

我一直试图做至少(I)与Function.prototype,我想出了这个:

Object.defineProperty(Function.prototype,"pow",{writable:true}); 
//Just so the function not enumerable using a for-in loop (my habit)
function forceSlice(context,argsArr)
{returnArray.prototype.slice.apply(context,argsArr)}
Function.prototype.pow = function(power)
{
  var args=power<2?forceSlice(arguments,[1]):
  [this.pow.apply(this,[power-1].concat(forceSlice(arguments,[1])))];
  return this.apply(0,args);
}
//Usage:
function square(a){return a*a;}
square.pow(4,2) //65536
function addThree(a,b){return a+(b||3); } 
// gives a+b when b exists and isn't 0, else gives a+3
addThree.pow(3,5,4) //15 (((5+4)+3)+3)

最坏的情况,我可能会选择eval,我还没有弄清楚。:/

编辑:Underscore.js,当玩了一点,可以满足这两个条件。我想到了这个,这是接近完成,但我不能让它工作:

_.partialApply = function(func,argList){_.partial.apply(_,[func].concat(argList))}
_.supercompose = function(func,instructions)
{
_.reduce(_.rest(instructions),function(memo,value)
{
return _.partialApply(_.partialApply(func, value),memo)();
},_.first(instructions))
}
//Usage:
_.supercompose(Math.pow,[[3,2],[_,2]]) //should be 81, instead throws "undefined is not a function"

编辑:jluckin's clear of terms(递归->函数组合)编辑:使示例函数返回数字而不是数组

您正在寻找的术语称为function composition,不一定是递归。你可以很容易地在javascript中应用函数组合,因为你可以将函数作为参数传递。

我创建了一个名为compose的小函数,它接受一个函数、一个初始值和组成该函数的次数。

function compose(myFunction, initialValue, numberOfCompositions) {
    if (numberOfCompositions === 1) {
        return myFunction(initialValue);
    }
    else {
        return compose(myFunction, myFunction(initialValue), --numberOfCompositions);
    }
}

当计算这个函数时,传入函数f(x)、初始值x0和重复计数。例如,numberofcomposates = 3给出f(f(f(x)));

如果有一个组合,则返回f(x)。如果有两个组合,compose返回f(x),其中f(x)代替x作为参数,并将1作为组合传入,因此它将计算f(f(x))。

此模式适用于任意数量的组合。

由于函数被视为对象,并且可以作为函数的参数传递,因此该方法基本上将"非递归"函数包装为递归函数,以允许组合。

成功(简单取胜):

_.supercompose = function (func,instructions,context)
{
var val;
for(var i = 0; i < instructions.length; i++)
  {
 val = _.partial.apply(_,[func].concat(instructions[i])).apply(context||this,val?[val]:[]);
  }
return val;
}
//Usage (with a function constructor for operations):
_.op = function(o){return Function.apply(this,"abcdefghijklmnopqrstuvwxyz".split("").concat(["return " + o]))}
_.op("a+b")(3,5) //-> 8
_.op("a*b")(3,5) //-> 15
_.supercompose(_.op("(a+b)*c*(d||1)"),[[1,2,3],[-5,_,1],[1,2,_,3]])
//-> (1+2)*((-5+((1+2)*3))*1)*3 -> 36