Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check how many times a char appears in a string

Simply trying to find how many times a given character appears in a string but I can't solve it any other way then this simple for-loop. Is there a method that would solve this quicker or more eloquently other than using Regex?

function countCharacter(str, char) {

  var count = 0;
  for(var i = 0; i < str.length; i++){
    if(str.charAt(i) === char)
      count++;
  }
 return count;
}
like image 784
ayeteo Avatar asked Aug 10 '17 02:08

ayeteo


2 Answers

There are many possible ways are available in the market. I am adding a few of them.

Method 1:

str = "The man is as good as his word"
str.split('a')
output: (4) ["The m", "n is ", "s good ", "s his word"]
str.split('a').length - 1
output: 3

Method 2:

str = "The man is as good as his word"
str.split('').map( function(char,i)
    { if(char === 'a') 
        return i;
    } 
).filter(Boolean)
Output: (3) [5, 11, 19]

str.split('').map( function(char,i)
    { if(char === 'a') 
        return i;
    } 
).filter(Boolean).length

ouput: 3

Edit: As per comment we can also make use of filter().

    str.split('').filter(function(char, i){
        if(char == 'a'){
            return i;
        }
    })
    output: (3) ["a", "a", "a"]

str.split('').filter(function(char, i){
    if(char == 'a'){
        return i;
    }
}).length
output: 3
like image 158
Neha Chopra Avatar answered Sep 30 '22 04:09

Neha Chopra


----edited by adding more cases from answers----

there are several ways, you can use split/for/regex/reduce/indexOf like this:

function countCharacter_reduce(str, ch) {
  return Array.prototype.reduce.call(str, (prev, cur) => cur === ch && ++prev && prev, 0);
}

function countCharacter_split(str, ch) {
  return str.split(ch).length - 1;
}

function countCharacter_for(str, ch) {
  for (var count = 0, ii = 0; ii < str.length; ii++) {
    if (str[ii] === ch)
      count++;
  }
  return count;
}

function countCharacter_regex(str, ch) {
  return str.length - str.replace(new RegExp(ch, 'g'), '').length;
}

function countCharacter_indexOf(str, char) {
  var start = 0;
  var count = 0;
  while ((start = str.indexOf(char, start) + 1) !== 0) {
    count++;
  }
  return count;
}

performance of them by running 1,000,000 times on counting '/' in a string.

-- case1: running 1000000 times on ( 'this/is/a/path/with/extension', '/' )
countCharacter_reduce: 2389.880ms
countCharacter_regex: 496.251ms
countCharacter_split: 114.709ms
countCharacter_for: 152.012ms
countCharacter_indexOf: 90.330ms

-- case2: running 1000000 times on ( '////////////', '/' )
countCharacter_reduce: 1138.051ms
countCharacter_regex: 619.886ms
countCharacter_split: 121.945ms
countCharacter_for: 74.542ms
countCharacter_indexOf: 204.242ms

Conclusion ('>' means 'has better performance'):

for|split|indexOf > regex > reduce.

furthermore, if the string contains more searching characters (like case2),

for>split>indexOf,

otherwise (like case1)

indexOf > split > for.

BTW: you can change the for indexOf method to fit multi-characters search (example is single character)

like image 25
aaron Avatar answered Sep 30 '22 04:09

aaron