How to implement a decision tree in javascript. Looking for a better solution than my ugly ones

I am looking for a better way to implement a decision tree in javascript. Being very new to programming, I have a very limited number of tools in my toolbar. The only thing I know is:. with a huge ugly, it’s hard to maintain and follow, unless otherwise, if the statement. I could use the switch / case statement and make the state type a state machine.

Suggestions and theories are welcome. In addition, small code examples would be very helpful. Thanks for watching.

Dale

+7
source share
2 answers

If this is a really big tree, and especially if it is generated from data, you can consider decision functions as data using a functional approach. For example:

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" 

Using this implementation, you can arbitrarily nest your tree:

 // 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; } }; 
+10
source

The best practice for this kind of thing is to embed if-then expressions in a meaningful way, and then incorporate them into your own function bodies. A function must not have more than two nested if; after that it’s acceptable to introduce additional nested ones, if in functions that are named and implemented well, thus abstracting the complexity of the program, while maintaining its value for the programmer who will read your code after you leave. :)

0
source

All Articles