开发者

Removing 3 nested if-then-else

开发者 https://www.devze.com 2023-03-10 18:57 出处:网络
I\'m seeing this code as the equivalent of a mathematica开发者_开发百科l permutation. It tries to set the value of $d based on a combination of $a, $b, $c. Right now it\'s being done with 3 nested if/

I'm seeing this code as the equivalent of a mathematica开发者_开发百科l permutation. It tries to set the value of $d based on a combination of $a, $b, $c. Right now it's being done with 3 nested if/then/else. Any other way the same thing can be done more efficiently?

if ($a === true) {
    if ($b > 0) {
        if ($c === true) {
            $d = 6;
        } else {
            $d = 2;
        }
        $e = $b;
    } else {
        if ($c === true) {
            $d = 4;
        } else {
            $d = 0;
        }
    }
} else {
    if ($b > 0) {
        if ($c === true) {
            $d = 5;
        } else {
            $d = 1;
        }
        $e = $b;
    } else {
        if ($c === true) {
            $d = 7;
        } else {
            $d = 3;
        }
    }
}

Notice there's $e = $b; at the end of

if ($a === true) {
    if ($b > 0) {
} else {
    if ($b > 0) {

I think I will just remove it out of the whole look and say

if ($b > 0) {

Any error with that logic for $e = $b;?


You could do this:

$vals = array(3,7,1,5,0,4,2,6);
$d = $vals[((int)($a === true) << 2) + ((int)($b > 0) << 1) + (int)($c === true)];
if ($b > 0) {
    $e = $b;
}

This takes each condition as a bit in a 3 bit value to determine the index of the value for d:

index = a·2^2 + b·2^1 + c·2^0

Each condition yields a boolean value that is converted to integer (see boolean to integer conversion) and then shifted according to the position of the bit it represents (see shift left operator <<).


Just write the assignments (in order) as:

$d = 0 + 2 + 4
$d = 0 + 2
$d = 0 + 4
$d = 0
$d = 1 + 4
$d = 1
$d = 1 + 2 + 4
$d = 1 + 2

then you just have

$d = ($a === true ? 0 : 1) + ($c === true ? 4 : 0) + (($b > 0) === $a ? 2 : 0)
if ($b > 0)
  $e = $b


<?php
$a = $argv[1] ? true : false; 
$b = $argv[2];
$c = $argv[3] ? true : false;
$d = 0;
$e = null;

// compute
if ($b > 0) {
  $e = $b;
  $b_bool = true;
}
else {
  $b_bool = false;
}

if (!$a) $d += 1;
if (!($a ^ $b_bool)) $d += 2;
if ($c) $d += 4;

echo "$d $e\n";

If you could rearrange the data a bit the XOR wouldn't be needed.

And obviously this could be easily compacted a bit with a single assignment, but I left it expanded to be more readable.


You could take a completely different approach with a bit flag thing.

  • Bit 0: 1 if $a == true
  • Bit 1: 1 if $b > 0
  • Bit 2: 1 if $c == true

This will give you eight different values, that you can compute and compare easily.

Pseudo-code:

d =  (a     ? 1 << 0 : 0)
   | (b > 0 ? 1 << 1 : 0)
   | (c     ? 1 << 2 : 0)

Edit: forgot to warn that this won't match with your current $d values, you'll have to remap or rework the above if that's possible. Just a suggestion.

0

精彩评论

暂无评论...
验证码 换一张
取 消