detect 4 permutations of 2 variable values in a switch case statement

折月煮酒 提交于 2019-12-10 19:59:21

问题


I have 2 variables, width and height as integers. Any of these can be positive or negative (not zero). So naturally there are 4 cases;

  1. width > 0 && height > 0
  2. width > 0 && height < 0
  3. width < 0 && height > 0
  4. width < 0 && height < 0

Now I want to take different action on each of these 4 cases without using 4 if statements.

Is there a way to aggregate these cases so that it can be put as a simple switch case

switch( aggregate ){
  case 1:
  case 2:
  case 3:
  case 4:
}

If there is no better way than using if for each then in 3D space you have 3 lengths (x,y,z) and there will be 27 if blocks.

I'm using javascript if that matters.


回答1:


In javascript this is quite easy, just turn the condition upside down:

switch(true)
{
    case (width > 0 && height > 0):
        break;
    case (width > 0 && height < 0):
        break;
    case (width < 0 && height > 0):
        break;
    case (width < 0 && height < 0):
        break;

    default:

}

This also works in VB6/VBA but not in many other languaguages like C++ and C#.

Here's a simple proof: http://jsfiddle.net/avuxj/




回答2:


You could treat each of your conditions (width positive, height positive) as a single boolean attribute and combine them to binary number and switch over it.

Pseudocode:

int v = (width > 0 ? 0 : 1) << 1 | (height > 0 ? 0 : 1) << 0;
switch (v) {
  case 0b00:
    // width < 0 && height < 0;
    break;
  case 0b01:
    // width < 0 && height > 0;
    break;
  case 0b10:
    // width > 0 && height < 0
    break;
  case 0b11:
    // width > 0 && height > 0
    break;
}

If the language of your choice doesn't have binary numeric literals, then it's not as readable, but you might be able to fix that with comments.

Also note that languages that support interpreting true as 1 and false as 0 will help make the int v = ... line shorter.




回答3:


You could do

var bits=0;
if(width > 0) {
     bits+=1;
}
if(height > 0) {
     bits+=2;
}

switch{bits} {
    case 0: //both negative
        //something
        break;
    case 1: //width positive, height negative
        //something
        break;
    case 2: //width negative, height positive
        //something
        break;
    case 3: //both positive
        //something
        break;
}

Although it is all bit confusing. (Especially if You have 3 values). You can use variables to make Your code bit clearer.

var WIDTH_POSITIVE_BIT=1;
var HEIGHT_POSITIVE_BIT=2;

var bits=0;
if(width > 0) {
     bits+=WIDTH_POSITIVE_BIT;
}
if(height > 0) {
     bits+=HEIGHT_POSITIVE_BIT;
}

switch{bits} {
    case 0: //both negative
        //something
        break;
    case WIDTH_POSITIVE_BIT: //width positive, height negative
        //something
        break;
    case HEIGHT_POSITIVE_BIT: //width negative, height positive
        //something
        break;
    case WIDTH_POSITIVE_BIT+HEIGHT_POSITIVE_BIT: //both positive
        //something
        break;
}

I'd say that this does not help to make the code much clearer.




回答4:


Can't do this without adding a little overhead.

s = ( width < 0 ) ? 0 : 1;
s += ( height < 0 ) ? 0 : 2;

switch(s) {
    case  0: // 00 => both < 0
    case  1: // 01 => width > 0, height < 0
    case  2: // 10 => width < 0, height > 0
    case  3: // 11 => both > 0
}

And this could work for a 3D case:

s = ( width < 0 ) ? 0 : 1;   //First bit for width
s += ( height < 0 ) ? 0 : 2; //Second bit for height
s += ( depth < 0 ) ? 0 : 4;  //Third bit for depth

switch(s) {
    case  0: // 0 0 0
    case  1: // 0 0 1
    case  2: // 0 1 0
    case  3: // 0 1 1
    case  4: // 1 0 0
    case  5: // 1 0 1
    case  6: // 1 1 0
    case  7: // 1 1 1
}

Of course assuming you can't have a 0 dimension.




回答5:


Several answers are logically correct. If you were doing this in C it would be:

s = ((width<0)<<1) | (height<0);
switch(s) {
....
}

This can make a huge difference. I have code that combines 9 conditions into a switch like this. The switch gets turned into a jump table and is much faster than evaluating a bunch of conditions. There is no branching, just the jump table. I can't really speak to anything java or java script though.

You may also do nested if statements:

if (witdh<0) {
    if (height<0) {
        // both negative
    }
    else {
        // only width negative
    }
 }
 else {
    if (height<0) {
        // only height negative
    }
    else {
        // both positive
    }
 }

I find mashing the condition bits together and using a switch to be more readable - especially if the number of conditions grows.



来源:https://stackoverflow.com/questions/7360600/detect-4-permutations-of-2-variable-values-in-a-switch-case-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!