检查字符串中字符出现的次数

时间:2017-08-10 02:12:12

标签: javascript arrays for-loop

只是试图找出给定字符出现在字符串中的次数,但我无法以其他方式解决这个简单的for循环。除了使用正则表达式之外,还有一种方法可以更快或更有说服力地解决这个问题吗?

function countCharacter(str, char) {

  var count = 0;
  for(var i = 0; i < str.length; i++){
    if(str.charAt(i) === char)
      count++;
  }
 return count;
}

5 个答案:

答案 0 :(得分:3)

市场上有许多可能的方法。 我正在添加其中一些。

方法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

方法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

编辑:根据评论,我们也可以使用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

答案 1 :(得分:1)

----通过添加答案中的更多案例进行编辑----

有几种方法,您可以像这样使用split / for / regex / reduce / indexOf:

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;
}

通过计算字符串中的“ /”来运行1,000,000次。

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

结论(“>”表示“具有更好的效果”):

for | split | indexOf> regex> reduce

更多, 如果该字符串包含更多搜索字符(例如case2),

for> split> indexOf

否则(例如case1)

indexOf> split> for

顺便说一句::您可以更改for indexOf方法以适合多字符搜索(例如,单个字符)

答案 2 :(得分:0)

我想这涉及你想要避免的正则表达式,但它很快:

function countCharacter(str, char) {
    return str.length - str.replace(new RegExp(char,"g"),"").length;
}

您也可以尝试Jaromanda建议的str.split(char).length-1方法。

或者,全力以赴地进行一些有趣的递归(将0传递给startingFrom):

function countCharacter(str, char, startingFrom) {
    var idx = str.indexOf(char, startingFrom);
    return idx == -1 ? 0 : 1 + countCharacter(str, char, idx + 1);
}

你可以以某种效率为代价摆脱烦人的额外争论:

function countCharacter(str, char) {
    var idx = str.indexOf(char);
    return idx == -1 ? 0 : 1 + countCharacter(str.substr(idx+1), char);
}

这里有一个针对速度进行优化的版本(根据jsperf,这比我的浏览器快3倍,比正则表达版快得多):

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

请注意,indexOf方法通常比手动迭代字符串快得多。见jsperf

答案 3 :(得分:0)

使用reduce

function countCharacter(str, char) {
    return str.split('').reduce((a, x) => x === char ? ++a : a, 0);
}

答案 4 :(得分:0)

你走了。一行代码

"hello".match(new RegExp('l','g')).length

'l'替换为此处的任何字符new RegExp('l','g')

str.match(new RegExp(char,'g')).length