user966588
user966588

Reputation:

how to make a better code of these nested-if conditions

I have a nested-if code like this

 if (condition1 or condition2 or condition3 ) {
           if  (condition1) {
           }
           elsif (condition2) {
           }
           elsif (condition3) {
           }
 }

Now obviously, conditions(1,2 and 3) are already checked on outer if, so I don't want them to be checked again in inner if-elsif statements. So my solution was, removing the outer if totally. But again this will make it go through if-elsif.

So what if there are like 10-15 conditions. Which one is better? Or Is there any other better solution?

Upvotes: 1

Views: 1106

Answers (6)

Jim Black
Jim Black

Reputation: 1482

Or this:

(condition1) ? run_statement1() :
(condition2) ? run_statement2() :
(condition3) ? run_statement3() : run_elsestatement() ;

I'm a fan of less typing. Another option, if your evaluated conditions produce 'unique' results, is to use the result as a key in a hash-of-functions. This removes the conditional checking above completely.

For instance, if the conditions were based on the value held in a scalar called '$var', then you could simply use those different values as the keys to the hash.

$conditionalFunctionHash{$var}->();

Upvotes: 0

Dave Sherohman
Dave Sherohman

Reputation: 46187

If your conditions are all tests on the value of the same variable, you can use given/when in Perl 5.10.1 and later:

use 5.010;

given ($foo) {
  when ('bar') { ... }                  # string literal
  when (4) { ... }                      # numeric literal
  when (qw[ xyzzy plugh ]) { ... }      # any of multiple literals
  when (/^whee+$/) { ... }              # regex match
  default { ... }                       # fallthrough if nothing matched
}

Upvotes: 2

ruben2020
ruben2020

Reputation: 1549

  1. Remove the outer if statements because all the conditions will be checked anyway by the inner if statements.

  2. If you arrange which if conditions according to priority as in condition1 is more important than condition2, then of course, you can't change the order of the checks.

  3. If you arrange which if conditions according to frequency of occurrence, then you can rearrange based on frequency, as you test or profile the program.

  4. If condition1 is true, then run statement1. If your statements are too long, then put them into subroutines and call them, so it would look neater.

    if    (condition1) {&run_statement1();}
    elsif (condition2) {&run_statement2();}
    elsif (condition3) {&run_statement3();}
    elsif (condition4) {&run_statement4();}
    elsif (condition5) {&run_statement5();}
    elsif (condition6) {&run_statement6();}
    elsif (condition7) {&run_statement7();}
    else               {&run_elsestatement();}
    
  5. Don't unnecessarily complicate or obfuscate the code. Keep it simple, readable and fulfilling your objectives.

Upvotes: 0

Miguel Prz
Miguel Prz

Reputation: 13792

perhaps the Switch control sentence may have sense in your code (in depends on the conditions you are checking). Take a look at the documentation of Switch.

Update Starting with the 5.10 perl release, there is a given/when control flow.

 use feature "switch";

Upvotes: 1

amon
amon

Reputation: 57590

The outer if is unneccessary.

Besides that, only three possible optimizations seem reasonable:

  1. profile the code before optimizing, and sort the if/else conditions so that the most common condition is tested first etc.
  2. Use a data structure to represent the conditions. Should you be testing for some sort of equality (if ($foo eq $bar){...}elsif($foo eq $baz){...}), then a hash can transform the lookup from linear to constant time:

    %hash = ($bar => sub{...}, $baz => sub{...});
    my $code = $hash{$foo} or do{"this is the trailing else"};
    $code->(); # execute the coderef
    

    This is wildly flexible, but includes the indirection of closures.

  3. If you have to re-check a condition, cache the result. The scope of a variable that was declared in a condition reaches into all subsequent conditions and blocks of the if/else chain:

    if ( my $cond1 = ... and ...) {
      ...
    } elsif ($cond1 and my $cond2 = ...) {
      ...
    } elsif ($cond2) {
      ...
    }
    

Upvotes: 3

Jayy
Jayy

Reputation: 14728

It depends how often your code is being executed. With complicated sets of if-statements, it's better to optimise for readability, since compared to most other operations they're cheap. However, in your example above, I would remove the outer statement altogether, it's simply unnecessary. Perl optimises code while it parses it anyway.

Upvotes: 2

Related Questions