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?

4
  • 10
    Such a thing obfuscates your code. You'd be better off making the assignment conditional, not the for loop increment. Commented Oct 29, 2015 at 14:36
  • 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. Commented Oct 29, 2015 at 15:44
  • 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! Commented Oct 29, 2015 at 15:53
  • 3
    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." Commented Oct 29, 2015 at 16:28

3 Answers 3

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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Just because it can be done doesn't mean it should be done
Increment expression has to increment or decrement a loop control variable value - so it should be along the language recommendation.
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.

4 Comments

Your for loop is much better but your solution will give a StringIndexOutOfBoundsException for some inputs
@VBCPP: Instead of leaving the comments here, I thought I would just update the answer. So, there you go.
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?
@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.
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();

1 Comment

+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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.