Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
168
rated 0 times [  170] [ 2]  / answers: 1 / hits: 16322  / 13 Years ago, sat, december 3, 2011, 12:00:00

I'm 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 toolbox. The only ways I know to do this are:
.with a huge ugly hard to maintain and follow if else if statement
.I could use a switch/case statement and do a state machine type thing.



Suggestions and theories are appreciated. Also, small code examples would be very helpful. Thanks for taking a look.



Dale


More From » logic

 Answers
10

If it is a really big tree, and especially if it is generated from data, you could treat the decision functions like 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;
}
};

[#88775] Thursday, December 1, 2011, 13 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
soniap

Total Points: 626
Total Questions: 119
Total Answers: 110

Location: Palestine
Member since Tue, Jul 20, 2021
3 Years ago
;