我正在寻找一种更好的方法来在 javascript 中实现决策树。作为编程新手,我的工具箱中的工具数量非常有限。我知道这样做的唯一方法是: . 很难维护和遵循 if else if 语句。我可以使用 switch/case 语句并执行状态机类型的事情。
建议和理论表示赞赏。此外,小的代码示例将非常有帮助。谢谢参观。
戴尔
我正在寻找一种更好的方法来在 javascript 中实现决策树。作为编程新手,我的工具箱中的工具数量非常有限。我知道这样做的唯一方法是: . 很难维护和遵循 if else if 语句。我可以使用 switch/case 语句并执行状态机类型的事情。
建议和理论表示赞赏。此外,小的代码示例将非常有帮助。谢谢参观。
戴尔
如果它是一棵非常大的树,特别是如果它是从数据生成的,您可以使用函数方法将决策函数视为数据。例如:
var decisionTree =
new Case( true, Array(
new Case ( function(n){ return n < 0; }, Math.sin ),
new Case ( function(n){ return n < 2; }, "0<= n < 2" ),
new Case ( true, "Greater than two " )));
decisionTree.evaluate(1); // evaluates to string "0<= n < 2"
decisionTree.evaluate(-Math.PI/2); // evaluates to -1
decisionTree.evaluate(5); // evaluates to string "Greater than two"
使用这个实现,你可以任意嵌套你的树:
// Represents a predicate and corresponding action to take if predicate is a
// match.
//
// predicate : true or Function( object ) returning a boolean.
//
// action : One of Function, Case, Array of Cases or other value (see
// Case.evaluate as to how each is applied)
//
//
Case = function (predicate, action) {
this.predicate = predicate;
this.action = action;
};
Case.prototype = {
nomatch : { match : false },
match : function (v) { return { match : true, result :v }; },
// Recursively test Cases and applies corresponding action on
// `object`.
//
// The action applied depends on the datatype of `action`:
//
// - Function : evaluates to `action( object )`
//
// - Case : A subsequent test is performed. Evaluates to whatever
// the Cases action evaluates to.
//
// - Array of Cases : Subsequent tests are performed. Evaluates to whatever
// the action of the first matching Case evaluates to.
//
// - Any other Value : Evaluates to itself
//
// returns object containing fields:
//
// match: boolean, indicates if Case was a match
//
// result: result of action applied
//
evaluate : function( object ) {
var match = this.predicate;
if ( match instanceof Function )
match = match( object );
if ( match ) {
if (this.action instanceof Function )
return this.match( this.action(object) );
if ( this.action instanceof Case )
return this.action.evaluate( object );
if ( this.action instanceof Array ) {
var decision;
var result;
for (var c = 0; c < this.action.length; c++ ) {
decision = this.action[c];
if ( decision instanceof Case ) {
result = decision.evaluate( object );
if (result.match)
return result;
} else throw("Array of Case expected");
}
return this.nomatch;
}
return this.match(this.action);
}
return this.nomatch;
}
};
此类事情的最佳实践是以有意义的方式嵌套 if-then 语句,然后将它们放入自己的函数体中。一个函数不应该有超过 2 个嵌套的 if;之后,可以在命名和实现良好的函数中进一步嵌套 if ,从而抽象程序的复杂性,同时保留它对程序员的意义,让程序员在你离开后阅读你的代码。:)