Home > Software design >  Attributed Value of Ternary Operator Resets After Each Loop
Attributed Value of Ternary Operator Resets After Each Loop

Time:02-17

I would like to be able to go through an inputted string and count the amount of times "good" is written and compare it to how many times "bad" is written. If the good and the bad match, then goodVbad==0 and it returns true. Otherwise it returns false.

The code worked fine when I was using if statements inside the for-loop, but when using the ternary operator it doesn't. While debugging, I realized that each time the for-loop moves onto the next element 'goodVbad' becomes zero again. Kind of stumped, would love some advice. Thanks!

public static boolean goodbadClean(String word) {
    String [] wordS;
    int goodVbad=0;
    String good="good";
    String bad="bad";
    word=word.toLowerCase();
    word=word.replaceAll(good, " good ");
    word=word.replaceAll(bad, " bad ");
    wordS=word.split(" ");
    for(String i:wordS) {
        goodVbad=i.equals(good)?goodVbad  
                :i.equals(bad) ?goodVbad--
                :goodVbad;
    }
    if(goodVbad==0) {
        return true;
    }
    
    return false;
}

CodePudding user response:

The problem is the postfix operator returns the old value, which you are assigning the variable, then increments. ie

goodVBad = goodVBad  ;  // returns the old value, so does nothing

so you should use the prefixed operator:

goodVBad =   goodVBad; // increments first, returning the new value

But both of these are hard to read and brittle.

If you must use ternaries, change your code to:

goodVbad  = i.equals(good) ? 1 : (i.equals(bad) ? -1 : 0);

However, nested ternaries are generally a style smell. I recommend instead:

if (i.equals(good)) {
    goodVBad  ;
} else if (i.equals(bad)) {
    goodVBad--;
}

CodePudding user response:

Assuming that the OP needs to count the frequency of a string pattern in a given string, then you could do something like this with Java 8 or older:

public class CountMatches {
    public static void main(String[] args) {
        String phrase1 = "goodbadbadgoodgoodbad"; // equal amount of good vs bad.
        String phrase2 = "goodbadbadgoodgoodbadbad"; // more bad than good.
        String phrase3 = "goodbadbadgoodgoodbadgood"; // more good than bad.

        // create capturing groups for "good" and "bad"
        String GOOD_REGEX = "(good)";
        String BAD_REGEX = "(bad)";

        Pattern gPattern = Pattern.compile(GOOD_REGEX);
        Pattern bPattern = Pattern.compile(BAD_REGEX);
        Matcher countGood = gPattern.matcher(phrase1);
        Matcher countBad = bPattern.matcher(phrase1);

        int count = 0;
        while (countBad.find()) {
            count--;
        }
        while (countGood.find()) {
            count  ;
        }

        System.out.println(count == 0);
    }
}

With Java 9 or later:

public class CountMatches {
    public static void main(String[] args) {
        String phrase1 = "goodbadbadgoodgoodbad"; // equal amount of good vs bad.
        String phrase2 = "goodbadbadgoodgoodbadbad"; // more bad than good.
        String phrase3 = "goodbadbadgoodgoodbadgood"; // more good than bad.

        String GOOD_REGEX = "(good)";
        String BAD_REGEX = "(bad)";

        Pattern gPattern = Pattern.compile(GOOD_REGEX);
        Pattern bPattern = Pattern.compile(BAD_REGEX);
        Matcher countGood = gPattern.matcher(phrase1);
        Matcher countBad = bPattern.matcher(phrase1);

        long cCount = countGood.results().count();
        long bCount = countBad.results().count();

        System.out.println(cCount - bCount == 0);
    }
}

My assumption is based on this line of code word=word.replaceAll(good, " good ");. This tells me that the expected input is something similar to the phrase variables I used for my testing.

  • Related