7
\$\begingroup\$

I want to find character sequence count in a given string.

Sample Input: aaaabbbbaaacccbbb

Output: a4b4a3c3b3

My below function is working great and giving me the same result. but can this be optimized?

function getCharCount(str) {
    var result = str.charAt(0);
    var count = 1;
    if (str.length == 1) {
        result += count;
        return result;
    } else {
        for(var i=1;i<str.length;i++) {
            if(str.charAt(i) != str.charAt(i-1)) {
                result += count + str.charAt(i);
                count = 1;
            } else {
                count++;
            }
            if (i == str.length - 1) {
                result += count;
            }
        }
        return result;
    }
}
\$\endgroup\$
12
\$\begingroup\$

I don't see any problem in your code except using of equality and inequality operators. Use strict equality(===) & inequality(!==) operators.


I'll suggest to use RegEx.

.replace(/(.)\1*/g, function(m, $1) {
    return $1 + m.length;
})

The RegEx (.)\1* will match a single non-line-break character and check if that is followed by the same character any number of times. m here is the complete match and $1 is the first chaptured group value i.e. the character.

var res = 'aaaabbbbaaacccbbb'
    .replace(/(.)\1*/g, function(m, $1) {
        return $1 + m.length;
    });
console.log(res);

\$\endgroup\$
3
\$\begingroup\$

First of all, the function name is misleading. Character count could imply the length of the input, or a map of unique characters and their counts, and I would not guess the current behavior from this name. This is more like some sort of compression. Actually this happens to have a name: Run Length Encoding.

The program tries to get the first character without verifying that there is a first character. JavaScript let's you get away with it, returning an empty string when the index is invalid, but this is sloppy coding. It would be better to reorganize the logic to avoid such practices.

Declaring var i inside the for loop is not a good practice, because that syntax send to imply that the variable's scope is in the loop, but that's not the case in JavaScript.

After the check on str.length where you return in the if branch, you could eliminate the else branch, reducing the nesting level of the code, making it easier to read.

Putting the above together, this would be slightly better:

var result,
    count = 1,
    i;

if (!str) {
    return "";
}

result = str.charAt(0);
for (i = 1; i < str.length; i++) {
    if (str.charAt(i) != str.charAt(i-1)) {
        result += count + str.charAt(i);
        count = 1;
    } else {
        count++;
    }
}

return result + count;
\$\endgroup\$
  • \$\begingroup\$ Thank you very much for the tips. but the other answer provided me an optimised solution with regex. so i can't accept your answer. sorry :) \$\endgroup\$ – Mr.7 Nov 25 '16 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.