0

I am getting multiple user inputs stored in a object, called inputObj, these properties then need to all be ranked out of 100, (attached is the current method for ranking one property), need to do this for up to 20 properties, so currently this is a method where im repeating myself alot.

The maths is all working fine and im gettign the wanted outputs, but need a tidier way to do this, suggestions?

The main issue is that the mathematical manipulations will change for each property, so a universal function applying to all the properties wont work

Thanks

if (inputObj.dyAGE <=5) {
    inputObj.dyAGE *= 5.5;  
    }       
else if (inputObj.dyAGE<=7) {
    inputObj.dyAGE -= 5;
    inputObj.dyAGE *= 16.5;
    inputObj.dyAGE += 33;       
    }
else if(inputObj.dyAGE<=11) {
    inputObj.dyAGE -= 7;
    inputObj.dyAGE *= 8.25;
    inputObj.dyAGE += 66;
    }
else if (inputObj.dyAGE<=16) {
    inputObj.dyAGE -= 17;
    inputObj.dyAGE = -inputObj.dyAGE;
    inputObj.dyAGE *= 6.6;
    inputObj.dyAGE += 66;       
    }   
else if(inputObj.dyAGE <= 19) {
    inputObj.dyAGE -= 20;
    inputObj.dyAGE = -inputObj.dyAGE;
    inputObj.dyAGE *= 11;
    inputObj.dyAGE += 33
    }   
else if (inputObj.dyAGE <= 30) {
    inputObj.dyAGE-31;
    inputObj.dyAGE = -inputObj.dyAGE;
    inputObj.dyAGE *= 3;
};
2
  • 3
    Did you possibly make a mistake on the first line of the last if body? Commented Feb 24, 2012 at 10:54
  • Oh yes i hadnt seen that, Answers have been great! but i forgot to explain that the mathematical manipulations change for each property so cant make a function and apply it to different properties Commented Feb 24, 2012 at 12:48

4 Answers 4

3

You could use a Function:

inputObj.dyAGE = convert_AGE(inputObj.dyAGE)

function convert_AGE(x) {

    if (x <= 5)
        return x * 5.5;  
    if (x <= 7)
        return (x - 5) * 16.5 + 33;
    etc

Also you can convert series of assignments (inputObj.dyAGE=...) into expressions, so that this

inputObj.dyAGE -= 17;
inputObj.dyAGE = -inputObj.dyAGE;
inputObj.dyAGE *= 6.6;
inputObj.dyAGE += 66;      

becomes this

(17 - x) * 6.6 + 66

or even

178.2 - 6.6 * x

Of course, you can use distinct functions for each property, like

      inputObj.dyAGE = convert_AGE(inputObj.dyAGE)
      inputObj.dyXYZ = convert_XYZ(inputObj.dyXYZ)

or automate this by creating a hash of functions:

   convertors = {
         'dyAGE': function(x) { code to convert age },
         'dyXYZ': function(x) { code to convert xyz },
          etc
    }

and then convert all properties at once

    for (var prop in input)
        if (prop in convertors)
            input.prop = convertors[prop](input.prop);
Sign up to request clarification or add additional context in comments.

Comments

0

Treat your object as an array and iterate over it like so:

for(var i in inputObj) {
   if (inputObj[i] <=5) {
      inputObj[i] *= 5.5;  
   }       
   ...
}

This assumes that all properties of inputObj should be treated the same. Also note that I have truncated your code to keep the sample simpler and easier to read.

Comments

0

You can modelize your business logic into class.

Something like that :

  • a class Operation which has a type (plus, minus, divide...) and a value
  • a class Constraint which contains a list of operation and a value

Then, create a list of Constraint (with a good constructor, you can instanciate a Constraint in one line of code). Loop onto this list. For each item, get the constraint value, do the if, then if necessary apply all operations (switch block on operation type).

The modelization is a bit more complex but if you need to add a lot of constraint, it is more maintenable and easy to add constraint.

Here is the final code: warning : i've not tested the code, there is maybe some syntax error, but the main philosophy is here.

var myConstraint = new Array();
myConstraint.push(5, {new Operation(Operation.TIME, 5.5)});
myConstraint.push(7, {new Operation(Operation.MINUS, 5), new Operation(Operation.TIME, 16.5), new Operation(Operation.PLUS, 33)});
...

for (var i = 0; i < myConstraint.length; i++) {
  var c = myConstraint[i];
  if (inputObj.dyAGE <= c.value) {
    var op = c.operations;

    for (var i = 0; i < op.length; i++) {
      switch (op[i].type) {
        case PLUS : inputObj.dyAge += op[i].value; break;
        case ...
      }
    }

    break;
  }
}

Comments

0

How about this:

var ages={
    min: 0,
    max: 11,
    '0': function (x){return 5.5;},
    '5': function (x){return x*5.5;},
    '7': function (x){return (x-5)*16.5+33;},
    '11': function (x){return (x-7)*8.25+66;}
}

function getRank(oper,prop){
    if(prop<oper.min || prop>oper.max) return false;
    var idx=prop,rank;
    while(!oper.hasOwnProperty(idx)){
        idx++;
        if(idx>oper.max) return false;
    }
    rank=oper[idx](prop);
    return rank;
}

Just add each constraint and it's mathematical expression to ages-object, as well change the max value according to the greatest constraint. This is easier to maintain than Jerome's code, thought Jerome's is also more effective (faster).

EDIT:

I'm sorry, I didn't notice your last comment. I've edited the code a bit. For different properties you create object like ages for each. Then the function call is for example:

getRank(ages,inputObj.dyAGE);

This code can be used with any non-negative integer in inputObj.dyAGE. If there's a need to use floating point values, those have to be converted integers when passing to getRank-function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.