4

我今天在工作中遇到了一种情况,我需要编写我已经编写的函数的逆函数,但是我发现手动编写逆函数效率很低,因为我似乎会重复很多代码,如果我要更新原始函数,我必须用相应的更改来更新逆函数。我正在谈论的功能看起来像这样:

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”子句更新原始函数,我也不必更新finverse. 换句话说,我不想finverse使用 if 语句手动构造以将输出映射回输入,而是我想以某种方式操纵原始函数以得出逆向函数。这在javascript中可能吗?

4

2 回答 2

3

通过轻微的重构,任务实际上非常简单。您不需要所有这些 if,实际上,if 的运行速度比 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% 确定...

于 2013-06-29T04:51:42.317 回答
1

真的没有办法让它完美地工作。这是不可能以良好的速度特性实现的。因此,我尝试为您提供两种解决此问题的方法:

  1. 使用. fRules_f()

    fRules = [
      { 
         id: 0,
         char: ' ',
         insertPosition: 4
      },
    
      // ... other rules ...
    ];
    

    然后,您可以简单地使用需要的规则来查找规则,fRules并迭代规则数组并找到好的规则。现在你不需要改变,只需;f()idfInversef()fRules()

  2. f.toString()获取函数文本并将函数解析为抽象语法树。就像 UglifyJs 的内部函数一样。在这里阅读更多。然后,您必须根据您的函数语法树手动编写一些逆变器。丑陋的想法

于 2013-06-29T03:12:23.650 回答