我遇到了今天工作的情况,我需要写一个我已经写过的函数的反函数,但是我发现手动编写反函数效率很低,因为看起来我会重复我的很多代码,如果我要更新原始函数,我将不得不用相应的更改更新逆。我正在谈论的功能看起来像这样:
var f = function(id, str) {
if (id === 0) {
return str.substring(0, 4) + " " + str.substring(4, 8);
} else if (id === 1) {
return str.substring(0, 3) + "/" + str.substring(3, 8);
} else if (id === 2) {
return str.substring(0, 4) + "-" + str.substring(4, 8);
} else if (id == 3) {
return str.substring(0, 3) + "," + str.substring(3, 8);
}
}
因此,例如f(0, "ABCDEFGH")
将返回"ABCD EFGH"
。我需要一个使用函数f(id, str)
的反函数来输出输出。所以finverse(formattedStr)
应该返回相应输入的字典。例如,finverse("ABCD EFGH")
应返回{ id: 0, str: "ABCDEFGH" }
。是否可以利用现有的函数f
来编写这个逆,这样即使我用额外的“else if”子句更新原始函数,我也不必更新{{1 }}。换句话说,我不想用if语句手动构造finverse
来将输出映射回输入,而是我想以某种方式操纵原始函数来得出逆。这可以在javascript中使用吗?
答案 0 :(得分:3)
稍加重新分解,任务实际上非常简单。你不需要所有那些ifs,实际上,ifs运行速度比Object属性查找慢,更不用说它们没有被封存在某个私有函数中......
我们可以在没有任何流逻辑的情况下完成翻译(1英寸,1英寸输出):
// replace all the IF logic with an externally-modifiable logic table:
f.lut=[ [4," "], [3,"/"], [4,"-"], [3,","] ]; //(id=index, 0=pos, 1=char)
// simplify f() using the table to make choices instead of conditionals:
function f(id, str) {
id = f.lut[id];
return str.substring(0, id[0]) + id[1] + str.substring(id[0], 8);
}
// use the same table in reverse to compose an inverse function:
function finverse(s){
return {
id: +f.lut.map(function(A,i){ return A[1]==s.split(/[\w]+/).filter(Boolean)[0] ?
String(i):
""
}).filter(Boolean)[0][0],
str: s.split(/[\W]+/).filter(Boolean).join('')
};
}
// first, test new version of f():
f(0, "ABCDEFGH") // ABCD EFGH
f(1, "ABCDEFGH") // ABC/DEFGH
f(2, "ABCDEFGH") // ABCD-EFGH
f(3, "ABCDEFGH") // ABC,DEFGH
// now, test the inverse:
finverse("ABCD EFGH") //{id:0, str:"ABCDEFGH"}
finverse("ABC/DEFGH") //{id:1, str:"ABCDEFGH"}
finverse("ABCD-EFGH") //{id:2, str:"ABCDEFGH"}
finverse("ABC,DEFGH") //{id:3, str:"ABCDEFGH"}
如果这不是您想要的,请告诉我们,我不是100%确定......
答案 1 :(得分:1)
真的没办法让它完美运作。这是不可能以良好的速度特性实现的。所以,我试着给你两种解决这个问题的方法:
使用fRules
中使用的规则创建名为f()
的全局对象。
fRules = [
{
id: 0,
char: ' ',
insertPosition: 4
},
// ... other rules ...
];
然后,您可以在fRules
中使用f()
,只需找到需要id
的规则,然后在fInverse
中迭代一系列规则并找到好的规则。现在您无需更改f()
,只需更改fRules()
;
f.toString()
获取函数和解析函数的文本以抽象语法树。像UglifyJs的内部功能一样。阅读更多here。然后,您必须根据函数语法树手动编写一些反转器。丑陋的想法