Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/435.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用JavaScript实现复杂的决策表_Javascript - Fatal编程技术网

用JavaScript实现复杂的决策表

用JavaScript实现复杂的决策表,javascript,Javascript,下面是JavaScript专家的一个实现细节问题 我有一个包含许多字段的UI,其中字段的值以一种复杂的方式依赖于七位输入的值。当用户看到更多应用程序时,可能会定期更改的128个值中的任何一个值的确切显示内容是什么 现在,我已经通过if-then-else梳将其实现为一个决策树,但是在需求变化的情况下,它很脆弱,很难正确实现 我考虑过的一种实现方法是创建一个从0x0到0x7F的值数组,然后在每个位置存储一个闭包-- 然后用 tbl[bitsIn](); 这至少让决策逻辑变成了一堆任务 问题:有更

下面是JavaScript专家的一个实现细节问题

我有一个包含许多字段的UI,其中字段的值以一种复杂的方式依赖于七位输入的值。当用户看到更多应用程序时,可能会定期更改的128个值中的任何一个值的确切显示内容是什么

现在,我已经通过if-then-else梳将其实现为一个决策树,但是在需求变化的情况下,它很脆弱,很难正确实现

我考虑过的一种实现方法是创建一个从0x0到0x7F的值数组,然后在每个位置存储一个闭包--

然后用

tbl[bitsIn]();
这至少让决策逻辑变成了一堆任务

问题:有更好的办法吗

(更新:天哪,那句关于“ajax iphone标签”的话是怎么出现的?难怪有点令人费解。)

更新

发生了什么事?基本上,我选择了第四个选项,尽管与我所选择的类似。逻辑非常复杂,我最终构建了一个Python程序,在服务器中生成一个真值表(生成代码,实际上,主机是一个应用程序),并将决策逻辑完全移动到服务器中。现在JavaScript端只是解释一个JSON对象,其中包含各个字段的值

最终,这可能会再经过一次迭代,并成为数据库表中的数据,通过位向量进行索引

桌子驱动的部分肯定是未来的发展方向;显示器的具体要求已经有六个新的变化。

由于情况(如您所述)如此不规则,似乎没有更好的方法。不过,我可以建议你改进一下跳台。你提到你有错误和重复。因此,您可以将它们指定给命名函数,而不是显式地将它们指定给闭包,这样就不必复制显式闭包

var doAThingAndAnother = function (){ doAThing(); doAnotherThing(); }

var tbl; // initialize it with the values
  ...
tbl[0x42] = doAThingAndAnother;
tbl[0x43] = doAThingAndAnother;
虽然没有多大进步,但这是我唯一能想到的!你似乎已经涵盖了大部分其他问题。由于需求变化如此之大,我认为您可能不得不放弃优雅,而设计得不那么优雅,但仍然很容易改变。

我看到两种选择

两种解决方案的共同点是以下命名函数:

function aThing() {}
function anotherThing() {}
function aThirdThing() {}
道岔

function exec(bits) {
 switch(bits) {
    case 0x00: aThing(); anotherThing(); break;
    case 0x01: aThing(); anotherThing(); aThirdThing(); break;
    case 0x02: aThing(); aThirdThing(); break;
    case 0x03: anotherThing(); aThirdThing(); break;
    ...
    case 0x42: aThirdThing(); break;
    ...
    case 0x7f: ... break;
    default: throw 'There is only 128 options :P';
  }
}
地图之路

function exec(bits) { 
    var actions = map[bits];
    for(var i=0, action; action=actions[i]; i++)
        action(); 
}

var map = {
 0x00: [aThing, anotherThing],
 0x01: [aThing, anotherThing, aThirdThing],
 0x02: [aThing, aThirdThing],
 0x03: [anotherThing, aThirdThing],
    ...
 0x42: [aThirdThing],
    ...
};
在这两种情况下,你都会打电话

exec(0x42);

您是否考虑过在服务器上生成决策树而不是手工编写?使用任何干净、易于使用的表示,然后修改并编译为丑陋但高效的javascript,用于客户端

决策树很容易表示为数据,并且作为传统的树数据结构很容易理解和使用。你可以用任何对你有意义的形式来储存这棵树。作为数据验证和修改它也应该是直接的


然后,当您需要使用决策树时,只需将其编译/序列化为一个大的JavaScript,如果else、switch或hash混乱的话。这也应该是相当直接的,可能比试图维护一个包含数百个元素的
开关要容易得多。

如果您想看一下,我有一个JavaScript决策树工具的粗略示例:


从我对您的问题的理解来看,您的重构思想是合理的,但从您的描述来看,我不确定您需要什么:PDO每一位都决定一个特定的操作?如果是这样,为什么不对[0x01、0x02、0x04、0x08、0x10、0x20、0x40]的值执行按位AND运算呢?@Martin,关键是是否有比我的lambdas表更灵活的方法来执行此操作。@draeton,这是一个好的观点。该表实际上是稀疏的(许多值只是无效的,表示错误,但不规则地)和冗余的(多个值可能附加了相同的操作,但又没有规则性)。如果这种关系是固定的,我可以将其转换为FSA,但我已经尝试过了,需求变化破坏了FSA。出于好奇,你决定了什么?您找到更好的解决方案了吗?该循环不能是(操作中的var action)action()的
?它可以,但没有什么意义。本例中的操作是一个函数引用数组,您不希望使用for(数组中的var i)在数组上循环,因为这样做速度要慢得多,而且会在不同浏览器中产生不均匀的结果。某些浏览器将数组上的“length”属性视为对象的另一个成员,并提供该属性以及函数引用。[].PropertySiEnumerable('length')==false
exec(0x42);