Search code examples
javascriptoptimizationcode-readability

Avoiding Repetition in Nested Conditional


With a nested conditional similar to the following, how might you optimize the branches for enhanced performance and/or readability? Because there are loops within many of the potential cases, it would be more efficient to consolidate the repetitive entries into a more practical function.

//a is defined either 1, 2, or 3
//b is defined either true or false

for(var i=0; i<hugeNumber; i++){
switch(a){
    case 1:
        if(b){
            for(objects in longlist){
                objects.color = object.c;
                objects.position = object.x
            }
        }else{
            for(objects in longlist){
                objects.color = object.c;
                objects.position = object.y
            }
    case 2:
        if(b){
            for(objects in longlist){
                objects.color = object.b;
                objects.position = object.x;
            }
        }else{
            for(objects in longlist){
                objects.color = object.b;
                objects.position = object.y;
            }
    case 3:
        if(b){
            for(objects in longlist){
                objects.color = blackColor;
                objects.position = object.x;
            }
        }else{
            for(objects in longlist){
                objects.color = blackColor;
                objects.position = object.y;
            }
}
}

It appears just as unreasonable to place the conditionals within an overarching for loop.

Ideally the target variable could be defined at the beginning, immediately when the conditions are known - as conditional a always yields color c for 0, color b for 1, and blackColor for 2, while conditional b always yields position x for true and position y for false.

I have seen variations of this question for PHP and Ruby, but am not quite sure how to apply the solutions to JavaScript. I can think of some ways that this might work, but I have so far not been able to make the code function syntactically.

UPDATE / SOLUTION: An answer prompted me to discover that this can be accomplished efficiently with eval():

var targetColor;
var targetPosition;

switch(a){
    case 1: targetColor = "objects.c"; break;
    case 2: targetColor = "objects.b"; break;
    case 3: targetColor = "blackColor"; break;
}
if(b){
    targetPosition = "objects.x";
}else{
    targetPosition = "objects.y";
}

for(var i=0; i<hugeNumber; i++){
    for(objects in longlist){
        objects.color = eval(targetColor);
        objects.position = eval(targetPosition);
    }
}

If there is a better approach than this I am absolutely open to additional suggestions - I know that eval can be sometimes dangerous.


Solution

  • Little less compact but quite readable and without unnecessary rechecks:

    var coord = b ? 'x' : 'y';
    var col = '';
    switch(a){
        case 1: col = 'c';
        case 2: col = 'b';
        // may add more cases...
    }
    for(objects in longlist) {
        object.color = object[col] || 'blackColor';
        object.position = object[coord];
    }