我想知道一个字符在字符串中出现的次数,但是我只能用简单的for循环解决问题。除了使用正则表达式之外,是否有更快捷、更优雅的方法可以解决这个问题?
function countCharacter(str, char) {
var count = 0;
for(var i = 0; i < str.length; i++){
if(str.charAt(i) === char)
count++;
}
return count;
}
我想知道一个字符在字符串中出现的次数,但是我只能用简单的for循环解决问题。除了使用正则表达式之外,是否有更快捷、更优雅的方法可以解决这个问题?
function countCharacter(str, char) {
var count = 0;
for(var i = 0; i < str.length; i++){
if(str.charAt(i) === char)
count++;
}
return count;
}
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
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
.map()
而不是单独使用.filter()
呢? - nnnnnn有几种方法可以实现,你可以使用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;
}
通过在字符串中运行100万次计数'/'来测试它们的性能。
-- 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
方法更改为适合多字符搜索(示例是单个字符)
function myFunction(str, char) {
return string.split(char).length - 1
}
请告诉我您对这个解决方案的看法。
我猜这涉及到正则表达式,而你想要避免它,但这很快:
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);
}
这里有一个经过速度优化的版本(在我的浏览器上比您的原始版本快约3倍,并且根据jsperf测试比正则表达式版本更快):
function countCharacter(str, char) {
var start = 0;
var count = 0;
while((start = str.indexOf(char, start)+1) !== 0) {
count++;
}
return count;
}
str.match(new RegExp(char, 'g')).length
。但是请注意,使用RegExp时需要小心char
的内容。 - Jaromanda Xstr.replace(new RegExp('[^' + char + ']','g'), '').length
。;-) 请注意,match 永远不会返回 0,而是会返回 null,并且 null.length
会抛出错误。:-( 所以也许可以使用 (str.match(new RegExp(char, 'g')) || []).length
。 - RobG使用reduce
函数:
function countCharacter(str, char) {
return str.split('').reduce((a, x) => x === char ? ++a : a, 0);
}
给你,一行代码
"hello".match(new RegExp('l','g')).length
将'l'
替换为任何字符,new RegExp('l','g')
。
就是这样
str.match(new RegExp(char,'g')).length
return str.split(char).length - 1;
,额外奖励,您还可以在字符串中搜索出现的字符串 :p - Jaromanda Xstr.charAt(i)
更改为str[i]
,以保持本质上相同的算法并减少函数调用。 除了使用正则表达式之外 - 为什么不使用正则表达式? - nnnnnn