Using if else in For Loop increment
Asked Answered
M

3

15

I have a problem in Java:

Given a string, return a string made of the chars at indexes 0,1,4,5,8,9...

I know how to solve it, however I was wondering if it's possible for me to use if-else in for-loop increment itself, for example:

for (int i=0; i < str.length(); if (i%4==0) i++, else i+=3){
    result += str.charAt(i);
}

Can we do something like that?

Margarettmargaretta answered 29/10, 2015 at 14:24 Comment(4)
Such a thing obfuscates your code. You'd be better off making the assignment conditional, not the for loop increment.Beall
To whoever answered suggesting me to leave increment blank and then put if-else in loop body but later deleted answer, I just wanted to thank you; I've never thought about that before.Margarettmargaretta
Yes I am aware that it would make code "ugly," I was just curious about a way to struct something; even if it's unnecessary. But thank you everyone for your time!Margarettmargaretta
It's not so much out of ugliness, but out of maintainability and readability. A perfect piece of code would have you say "Ah, I immediately understand what's going on."All
V
35

You can't use an if there but you can use a ternary operator

for (int i = 0; i < str.length(); i += i%4 == 0 ? 1 : 3) {
    result += str.charAt(i);
}
Ventricular answered 29/10, 2015 at 14:27 Comment(2)
Just because it can be done doesn't mean it should be doneSciurine
Increment expression has to increment or decrement a loop control variable value - so it should be along the language recommendation.Marje
M
9

Putting it simply, you want two characters from every 4th position starting from 0. You can use the following code for that:

StringBuilder builder = new StringBuilder();
for (int i = 0; i < safeLength; i += 4){
    builder.Append(str.substring(i, i + 2));
}

Unlike the answer that you have accepted, in this answer there is:

  • no obfuscation;
  • the intent is very clear; and,
  • most importantly, no if-else or ternary operator.

Update: I'm aware of the possibility of IndexOutOfBoundsException but because I wanted to keep the attention on core logic only, I didn't add that check. Here is the code that needs to be added to avoid the exceptional cases:

Put following code above the for loop:

int safeLength = str.Length();
bool lengthCorrectionWasNeeded = (str.length() - 1) % 4 == 0;
if (lengthCorrectionWasNeeded) safeLength--;

Put following code below the for loop:

if (lengthCorrectionWasNeeded) builder.append(str.substring(str.length() - 2));

At the end builder.ToString() will contain the desired string.

Martyrology answered 29/10, 2015 at 20:18 Comment(4)
Your for loop is much better but your solution will give a StringIndexOutOfBoundsException for some inputsSciurine
@VBCPP: Instead of leaving the comments here, I thought I would just update the answer. So, there you go.Martyrology
Thank you, it's pretty much what my original solution was, but without StringBuilder. Never seen it, so I take that I should use it if I'm going to modify single string a lot?Margarettmargaretta
@micahwood50: Yes, you should use StringBuilder if there is going to be a lot of string based addition-subtraction. And you should definitely read this Sad Tragedy and Horses.Martyrology
O
8

As for the issue "Using if else in For Loop increment", I agree with Manos's answer. The following are some of my suggestion. In my opinion, it is important that codes are clear and clean. And it is a good practice that extract str.length() to a local variable instead of 'calculating' it in every loop. And if you are building a string by appending it lots of time, StringBuilder is a good choice.

    String str = "this is your string ...";
    int length = str.length();
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < length ; i += (i%4 == 0 ? 1 : 3)){
       builder.append(str.charAt(i));
    }
    String result = builder.toString();
Og answered 29/10, 2015 at 14:52 Comment(1)
+1 for the suggestion to use StringBuilder. Calling str.length() on each iteration however isn't a performance issue. This method just returns the length property of the underlying char[] and it's very likely to be inlined. It's not "calculating" anything.Ventricular

© 2022 - 2024 — McMap. All rights reserved.