Jump to content

Simplify Code


Deejtko

Recommended Posts

I have two rules currently that work together. One determines a discount percentage for the state the person lives in. The other has the discount text for said state and inserts the percentage determined in the first rule. It seems to take forever to compose this job so I am thinking maybe it is because of these rules. It has been ages since I have worked with variables and things aren't working out too well. Below is an example of my current code:

 

 

switch (Trim(Field("DataState")).toLowerCase())

{

case "Alabama".toLowerCase():

 

switch (Trim(Field("Description")).toLowerCase())

{

case "Driver".toLowerCase():

return "10";

case "Teacher".toLowerCase():

return "15";

 

case "Alabama".toLowerCase():

 

switch (Trim(Field("Description")).toLowerCase())

{

case "Cook".toLowerCase():

return "10";

case "Parent".toLowerCase():

return "15";

}

}

 

 

switch (Trim(Field("DataState")).toLowerCase())

{

case "Alabama".toLowerCase():

return "Ask about our " +Rule("StatesDiscounts") + "% program discount.";

 

case "Arizona".toLowerCase():

return "Ask how you can save " +Rule("StatesDiscounts") + "%.";

}

This is just a sample of the code. There are many different discounts for each state. Basically I want to combine these two sets of code into one rule and it isn't working out for me.

 

Thanks for your help in advance.

Link to comment
Share on other sites

Do you have the same description values for multiple states and does a specific value always carry the same discount regardless of state (i.e. Driver gets 10% discount in all states that Driver exists as a value)? I'm thinking you could set up associative arrays as JavaScript globals and then reference them in your rule to simplify your code.

 

On a side note, it would be easier to write

case "alabama":

instead of

case "Alabama".toLowerCase():

Link to comment
Share on other sites

Thanks for the reply. The values are different for each state as are the descriptions. Some states, so far, will have up to 15 descriptions. My goal was to find the discount then "move" down in the same rule and use the discount in the sentence for that state.
Link to comment
Share on other sites

I would consolidate your code into one rule and remove a lot of the "redundant" code as follows:

var discText = "";
var discAmt = "";
switch (Trim(Field("DataState")).toLowerCase()) {
   case "alabama":
   discText = "Ask about our [d]% program discount.";
   switch (Trim(Field("Description")).toLowerCase()) {
       case "driver":
       discAmt = "10";
       break;

       case "teacher":
       case "student":
       case "weaver":
       discAmt = "15";
       break;

       case "baker":
       discAmt = "18";
       break;

       // etc
       }
   break;

   case "arizona":
   discText = "Ask how you can save [d]%";
   switch (Trim(Field("Description")).toLowerCase()) {
       case "cook":
       case "teacher":
       discAmt = "10";
       break;

       case "parent":
       discAmt = "15";
       break;

       case "engineer":
       case "military":
       discAmt = "18";
       break;

       // etc
   }
   break;

   // continue with cases for each state in same format
   // as above, you can list multiple cases with the same code back-to-back
   // don't forget the break code after each case

}
return discText.replace("[d]", discAmt);

However, I think your greatest issue (unless you just forgot to add it in your post's code) is forgetting to add a break statement at the end of each case's commands to avoid running through all the inapplicable code for each record. You may want to try adding the break command to your existing rules before starting from scratch with my modified logic.

Link to comment
Share on other sites

A few things here:

Do you have the same description values for multiple states and does a specific value always carry the same discount regardless of state (i.e. Driver gets 10% discount in all states that Driver exists as a value)? I'm thinking you could set up associative arrays as JavaScript globals and then reference them in your rule to simplify your code.

Yes, this is a great way to handle this kind of mapping logic. By "mapping," I don't mean like showing a street map of an area, I mean using a lookup table, or map, to match keys (state names in this case) to unique values.

 

JavaScript makes this really easy to do, since all objects basically have a map, or associative array, of properties. Also, once an object's properties have been set, accessing them is really fast, much faster than executing a switch statement. And this mapping can be done even if each job description (teacher, student, etc.) has a different discount rate per state. More on this in a bit....

 

On a side note, it would be easier to write

case "alabama":

instead of

case "Alabama".toLowerCase():

Yes, but this logic looks like it was converted from a Switch Wizard rule, which outputs the less succinct version, so that it maintains exactly the data typed in by the user in the Wizard. But that change won't have much of an impact on the execution time anyway.

However, I think your greatest issue (unless you just forgot to add it in your post's code) is forgetting to add a break statement at the end of each case's commands to avoid running through all the inapplicable code for each record. You may want to try adding the break command to your existing rules before starting from scratch with my modified logic.

I disagree with this. You don't need a "break" statement if you already have a "return" statement. The "return" statement short-circuits execution of the entire function, not just the "case" block of the "switch" statement.

 

But you're on the right track. There are a lot of ways you could skin this cat. You could create two functions, each with a switch statement and "return" lines, instead of two separate rules. You could create a couple of associative arrays. You could combine several different patterns.

 

But I think the best solution, to maximize both the execution speed and the readability of the code to manage the various discount rates and blurbs, is to create a single object which holds a two-dimensional associative array to contain everything. Something like this:

var Discounts = {
   alabama: {
       _text: "Ask about our [d]% program discount.",
       driver: 10,
       teacher: 15,
       // etc.
   },
   alaska: {
       _text: "Ask how you can save [d]%",
       cook: 10,
       parent: 15,
       // etc.
   },
   "new york": {
       _text: "Hey buddy, you can save [d]%!",
       "taxi driver": 1,
       pedestrian: 80,
       "bike messenger": 99,
       // etc.
   },
   // etc.
};

var discAmt = Discounts[Field("DataState").toLowerCase()][Field("Description").toLowerCase()];
var discText = Discounts[Field("DataState").toLowerCase()]._text;
return discText.replace("[d]", discAmt);

You can see how it's really easy to manage the data now, since it's all in one place and not mixed in with all the conditional logic that accesses it. Actually, the conditional logic all kind of goes away, since it's really just accessing properties. And the execution should be a lot faster too.

 

(Note that you can use quotes around the property names if they contain spaces, such as "new york" above.)

 

Now, the way to really make this go really fast, especially for your final composition, is to put the declaration of the object (Discounts) into the JavaScript Globals, so that its properties get initialized only once for the entire job, instead of once per record when the rule is executed. Then your rule will just be those last few lines. I can't think of anything that would be faster in JavaScript.

 

I've left out some validation logic to handle cases where the data fields don't match state names or job descriptions in the code, but that's not to hard to add.

Link to comment
Share on other sites

Of course, since this is just a two-dimensional array of data, you could also type it all into a tab-delimited file, a CSV file, or a similar delimited text file (either in a text editor or in your favorite spreadsheet application such as Microsoft Excel), where each row contains a state name, the text blurb, and a column for each job description, then read that data into FusionPro with ExternalDataFileEx.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...