Home > Mobile >  Multivariable for loop with conditional increment/decrement
Multivariable for loop with conditional increment/decrement

Time:06-28

Is there a neat way to do something like this?

        for (int left = 0, right = height.length - 1;
         left < height;
         height[left] < height[right] ? left   : right--)

I will be increasing left only if the condition is true. Otherwise, right will be decremented. I know I can do this inside the for loop and change the whole structure of the for loop around. But I was just curious if it was possible to have conditionals inside the for loop decrement/increment block.

CodePudding user response:

Yes, you can do that, but I don't see why you would want to. However, to make it work, we just need to make sure that the loop uses valid statements.

Remember that a for loop consists of:

for (initialization; termination; increment) {
    statement(s)
}

Your last section (the increment) is not a valid statement:

height[left] < height[right] ? left   : right--

But we can make it valid by assigning the result to a dummy value:

dummyValue = height[left] < height[right] ? left   : right--

And the working result of a one line for loop with no contents:

int someValue  = 0;
for (int left = 0, right = height.length - 1; left < height.length; someValue = height[left] < height[right] ? left   : right--);

Or for the sake of showing that it works you can add some debugging:

int someValue  = 0;
for (int left = 0, right = height.length - 1; left < height.length; someValue = height[left] < height[right] ? left   : right--){
    //Debugging to show that it works
    System.out.println("Left: " left " Right: " right);
}

Example output when height[] = {2,1,6,3,4,5} before it throws an exception:

L: 0 R: 5
L: 1 R: 5
L: 2 R: 5
L: 2 R: 4
L: 2 R: 3
L: 2 R: 2
L: 2 R: 1
L: 2 R: 0

Note that left and right are not accessible outside/after the for loop, so this usage has absolutely no meaning other than updating the value of someValue which has little use?

If you want to make this sort of one line for loop useful then change values that are declared prior to the loop, or have the loop call a method. For example below we create a method someMethod that replaces height[left] < height[right] and returns the result of it, but we can also perform an action in the method:

public static void main(String[] args) {
    int height[] = new int[]{...};
    int someValue = 0;
    //Call a method that does the any work we need
    for (int left = 0, right = height.length - 1; left < height.length; someValue = someMethod(height, left, right) ? left   : right--);
}

//The method we call
static boolean someMethod(int[] height, int left, int right){
    //Some action here
    //Note that edits left and right here will not be reflected in the for loop
    //...
    
    //Return the original check
    return height[left] < height[right];
}

CodePudding user response:

For loop is more suitable when you know no of execution times. While loop is more suitable when loop execution breaks based on some condition other than no of execution.

As @Haoliang, suggests while is more suitable in this case vs for loop.

Here slightly different For loop version.

for (int left = 0, right = height.length - 1; left < height; ) {

    height[left] < height[right] ? left   : right--;
}

Alternative while-loop version, which I think is less clutter

int left = 0, right = height.length - 1;
while ( left < height ) {
    height[left] < height[right] ? left   : right--;
} 
  • Related