我有两个JavaScript函数stack(y,f)和val(yi,x)。
stack(y,f)应该表现得像 y.map(function(yi) { f } )
它返回一个数组r,其中每个元素r [i]是数组参数y [i]和作为第二参数传递的表达式f的相应元素的函数。
f可以是任何计算为单个值的javascript代码,但是,如果它取决于函数val,则此函数将取决于y [i]。
[r[0], r[1], ...] = stack( [y[0], y[1], ...], foo( val(y[i], x1), val(y[i], x2), ... ) )
我考虑了以下丑陋的方法,将表达式作为字符串传递,并在循环中替换字符串-然后对其求值。https://jsfiddle.net/zuyt954g/
function val(yi,x) {
return 10**yi+x;
}
function foo(x1,x2,x3) {
return x1+x2+x3;
}
function stack(y,f) {
return y.map(function(yi) {
return eval(f.replace(/yi/g, yi));
});
}
console.log([1,2].map(function(yi) {
return foo(val(yi,3),val(yi,4),val(yi,5))
} ))
>> [42, 312]
console.log(stack([1,2], "foo(val(yi,3),val(yi,4),val(yi,5))"))
>> [42, 312]
我想知道您是否可以看到任何更简洁的解决方案,理想情况下,我将避免评估字符串表达式。作为替代方案,如果它检测到堆栈是其远距离父级之一,我想到已经val返回一个数组,但是获得调用堆栈和y似乎并不重要。
任何更清洁的解决方案,理想情况下,我将避免评估字符串表达式
很简单,只需使用一个函数即可。您摆脱了非常容易出错的字符串,使代码更易于维护,并使其更易于阅读和理解。
字符串"foo(val(yi,3),val(yi,4),val(yi,5))"
可以转换为函数:
function(yi) {
return foo(val(yi,3),val(yi,4),val(yi,5));
}
并且当调用而不是替换字符串时yi
,现在您只需将其传递即可,因此
eval(f.replace(/yi/g, yi));
变成简单
f(yi);
以下是此转换的外观:
function val(yi, x) {
return 10 ** yi + x;
}
function foo(x1, x2, x3) {
return x1 + x2 + x3;
}
function stack(y, f) {
return y.map(function(yi) {
return f(yi);
})
}
console.log([1, 2].map(function(yi) {
return foo(val(yi, 3), val(yi, 4), val(yi, 5))
}))
//>> [42, 312]
console.log(stack([1, 2], function(yi) {
return foo(val(yi, 3), val(yi, 4), val(yi, 5))
}))
//>> [42, 312]
但是,现在我们可以对其进行一些改进。这里有一些冗余:
return y.map(function(yi) {
return f(yi);
})
map
接收一个带有一个参数的回调,并调用另一个也带有相同参数的函数。这两个函数的偶数均为1,匿名回调的唯一目的是将参数转发给f
。因此,使用调用匿名回调与yi
调用相同f(yi)
。我们可以通过Lambda Calculus中称为Eta减少的方式删除此“空包装器”,因为f
它与回调完全相同。在我们的情况下,这意味着stack
:
function stack(y, f) {
return y.map(f)
}
最后一点,我们只需重用函数就可以进一步证明相等性
function(yi) {
return foo(val(yi, 3), val(yi, 4), val(yi, 5))
}
现在存在两次:
function val(yi, x) {
return 10 ** yi + x;
}
function foo(x1, x2, x3) {
return x1 + x2 + x3;
}
function stack(y, f) {
return y.map(f);
}
function testFunction(yi) { // ---|
return foo(val(yi, 3), val(yi, 4), val(yi, 5)); // |->-
} // ---| |
// v
// |
console.log([1, 2].map(testFunction)) //<-----------------<--
//>> [42, 312] |
// v
// |
console.log(stack([1, 2], testFunction)) //<--------------<--
//>> [42, 312]
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句