简体   繁体   中英

Split single line if statement into multiline if statements

I am trying to split single line if statement into multiline if statement with the same meaning. I have:

 if(a || (b && c))
 {
    /* do smt */
 } 

but would like to change it to something like if I would have

if(a && b && c)
{
  /*do smt*/
}

with the same meaning of

if(a)
{
  if(b)
  {
     if(c)
     {
         /* do smt */
     }
  }
}

Thanks!

Boolean algebra can turn this condiiton

a || (b && c) into

(a || b) && (a || c)

so you can do somthing like:

if(a || b)
 {
    if(a || c){
    /* do smt */
 } 
}

You can't really do this without repeating the body of the if block. You can transform a || b a || b to !(!a && !b) , but while this uses an && , you can't split this up into nested if statements due to the surrounding !(...) .

Why do you want to do this in the first place? My assumption would be that the three conditions a , b and c are very long and/or complex. If this is the case, I'd suggest one of the following:

  • declare three boolean variables with descriptive names and use those in the condition

     boolean isLoggedIn = // some really long data base lookup boolean isGuest = // more data base stuff boolean guestCanEdit = // a complex boolean expression if (isLoggedIn || (isGuest && guestCanEdit)) { ... 
  • define three methods performing the above checks and use those in the if

     if (isLoggedIn(user) || (isGuest(user) && guestCanEdit(topic))) { ... 

Note, however, that the first version does not use short-circuiting, ie all the conditions will be evaluated, even if the first is already true or the second is false. This should be avoided if any of the conditions in computationally expensive or eg if the third check is only possible if the second succeeds (eg after a null check).


Concerning your comment : The condition

if (list.isEmpty() || 
        (!list.isEmpty() && list.getLast().compareTo(heap.peek().value) <= 0))

is not really that long, and I would not suggest any of the above methods for this, as it will not get much shorter that way. But you can shorten it, because the b part is redundant. Due to the short-circuiting of || , (b && c) are only evaluated if !a , and since your b is !a , you can shorten it to just a || c a || c

if (list.isEmpty() || list.getLast().compareTo(heap.peek().value) <= 0)

If your goal is to count how many times compareTo is called, you can use this:

if (! list.isEmpty() && list.getLast().compareTo(heap.peek().value) <= 0)

Now this is just b && c , with the a part entirely missing. Note that this is not equivalent to a || (b && c) a || (b && c) anymore, but in this case that's a good thing, because due again to the short-circuiting, compareTo would actually not be called in a || c a || c if a already evaluated to true .

Yes you can do this, but perhaps you shouldn't.


if (a && b) statement;

is exactly equivalent to

if (a){
    if (b){
        statement;    
    }
}

But the same can't be said for if (a || b) : you'd need to write statement; in more than one place:

if (a){
    statement;
} else if (b){
    statement;
}

That said, || does distribute across && , even with the short-circuiting property:

So

if (a || b && c/*redundant parentheses removed*/){
    statement;
}

can be written as

if ((a || b) && (a || c)){
    statement;
}

which, from above, is

if (a || b){
    if (a || c){
        statement;
    }
}

which, although unnecessarily obfuscated, is what you want.

The need for this is not very clear, but you could do this: Make it in a function:

function codeToDo() {
  // your code to execute on condition
}

if (a) {
  codeToDo();
else if (b) {
  if (c) {
    codeToDo();
  }
}
if(a || b)
 {
     if(a || c){
    /* do smt */
     }
 }

To further handle if(a||b) part, apply:

if(a){
   /*do task1*/
}else if(b){
   /*do task1*/
}

Note that in the if(a) as well as else if(b) , you are running same code;ie task1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM