467 javascript string
我需要计算一个字符串中出现的字符数.
例如,假设我的字符串包含:
var mainStr = "str1,str2,str3,str4";
Run Code Online (Sandbox Code Playgroud)
我想找到逗号,字符的计数,即3.以逗号分割后的单个字符串的计数,即4.
我还需要验证每个字符串,即str1或str2或str3或str4不应超过15个字符.
Bjo*_*orn 683
我已经更新了这个答案.我更喜欢使用匹配的想法,但速度较慢:
console.log(("str1,str2,str3,str4".match(/,/g) || []).length); //logs 3
console.log(("str1,str2,str3,str4".match(new RegExp("str", "g")) || []).length); //logs 4
Run Code Online (Sandbox Code Playgroud)
如果您事先知道要搜索的内容,请使用正则表达式文字,否则可以使用RegExp构造函数,并将该g标志作为参数传入.
match返回null没有结果因此|| []
我在2009年做出的原始答案如下.它不必要地创建一个数组,但使用拆分更快(截至2014年9月).我很矛盾,如果我真的需要速度,毫无疑问我会使用分裂,但我宁愿使用匹配.
旧答案(2009年起):
如果您正在寻找逗号:
(mainStr.split(",").length - 1) //3
Run Code Online (Sandbox Code Playgroud)
如果你正在寻找str
(mainStr.split("str").length - 1) //4
Run Code Online (Sandbox Code Playgroud)
在@Lo的答案和我自己的愚蠢的jsperf测试中,两者都在速度方面领先,至少在Chrome中,但再次创建额外阵列似乎并不健全.
Lor*_*uer 204
至少有四种方式.最佳选择,也应该是本机RegEx引擎的最快 - 位于顶部.jsperf.com目前正在关闭,否则我会为您提供性能统计数据.
更新:请在此处查找性能测试,并自行运行,以便提供性能结果.稍后将给出结果的具体细节.
("this is foo bar".match(/o/g)||[]).length
//>2
Run Code Online (Sandbox Code Playgroud)
"this is foo bar".split("o").length-1
//>2
Run Code Online (Sandbox Code Playgroud)
拆分不推荐.资源匮乏.为每个匹配分配"Array"的新实例.不要通过FileReader尝试> 100MB的文件.您可以使用Chrome的分析器选项轻松地观察EXACT资源使用情况.
var stringsearch = "o"
,str = "this is foo bar";
for(var count=-1,index=-2; index != -1; count++,index=str.indexOf(stringsearch,index+1) );
//>count:2
Run Code Online (Sandbox Code Playgroud)
搜索单个字符
var stringsearch = "o"
,str = "this is foo bar";
for(var i=count=0; i<str.length; count+=+(stringsearch===str[i++]));
//>count:2
Run Code Online (Sandbox Code Playgroud)
更新:
元素映射和过滤,由于其整体资源预分配而不是使用Pythonian'generator'而不推荐
var str = "this is foo bar"
str.split('').map( function(e,i){ if(e === 'o') return i;} )
.filter(Boolean)
//>[9, 10]
[9, 10].length
//>2
Run Code Online (Sandbox Code Playgroud)
分享: 我用这8个字符统计方法制作了这个要点,所以我们可以直接汇集和分享我们的想法 - 只是为了好玩,也许是一些有趣的基准:)
https://gist.github.com/2757250
小智 19
将此函数添加到sting原型:
String.prototype.count=function(c) {
var result = 0, i = 0;
for(i;i<this.length;i++)if(this[i]==c)result++;
return result;
};
Run Code Online (Sandbox Code Playgroud)
用法:
console.log("strings".count("s")); //2
Run Code Online (Sandbox Code Playgroud)
Joe*_*app 18
更新:这可能很简单,但不是最快的。请参阅下面的基准。
令人惊奇的是,13年来,这个答案却没有出现。直觉上,它似乎应该是最快的:
const s = "The quick brown fox jumps over the lazy dog.";
const oCount = s.length - s.replaceAll('o', '').length;
Run Code Online (Sandbox Code Playgroud)
如果字符串中只有两种字符,则速度更快:
const s = "001101001";
const oneCount = s.replaceAll('0', '').length;
Run Code Online (Sandbox Code Playgroud)
基准
const { performance } = require('node:perf_hooks');
const ITERATIONS = 10000000;
const TEST_STRING = "The quick brown fox jumps over the lazy dog.";
console.log(ITERATIONS, "iterations");
let sum = 0; // make sure compiler doesn't optimize code out
let start = performance.now();
for (let i = 0; i < ITERATIONS; ++i) {
sum += TEST_STRING.length - TEST_STRING.replaceAll('o', '').length;
}
let end = performance.now();
console.log(" replaceAll duration", end - start, `(sum ${sum})`);
sum = 0;
start = performance.now();
for (let i = 0; i < ITERATIONS; ++i) {
sum += TEST_STRING.split('o').length - 1
}
end = performance.now();
console.log(" split duration", end - start, `(sum ${sum})`);
Run Code Online (Sandbox Code Playgroud)
10000 iterations
replaceAll duration 2.6167500019073486 (sum 40000)
split duration 2.0777920186519623 (sum 40000)
100000 iterations
replaceAll duration 17.563208997249603 (sum 400000)
split duration 8.087624996900558 (sum 400000)
1000000 iterations
replaceAll duration 128.71587499976158 (sum 4000000)
split duration 64.15841698646545 (sum 4000000)
10000000 iterations
replaceAll duration 1223.3415840268135 (sum 40000000)
split duration 629.1629169881344 (sum 40000000)
Run Code Online (Sandbox Code Playgroud)
use*_*751 10
一个快速的谷歌搜索得到了这个(来自http://www.codecodex.com/wiki/index.php?title=Count_the_number_of_occurrences_of_a_specific_character_in_a_string#JavaScript)
String.prototype.count=function(s1) {
return (this.length - this.replace(new RegExp(s1,"g"), '').length) / s1.length;
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
test = 'one,two,three,four'
commas = test.count(',') // returns 3
Run Code Online (Sandbox Code Playgroud)
您还可以休息您的字符串并像使用元素数组一样使用它
const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].filter(l => l === ',').length;
console.log(commas);Run Code Online (Sandbox Code Playgroud)
或者
const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].reduce((a, c) => c === ',' ? ++a : a, 0);
console.log(commas);Run Code Online (Sandbox Code Playgroud)
只需使用拆分即可找出字符串中字符出现的次数。
mainStr.split(',').length //给出4,这是使用定界符逗号分割后的字符串数
mainStr.split(',').length - 1 // //给出3,这是逗号的计数
更新06/10/2022
因此,我运行了各种性能测试,如果您的用例允许,似乎使用 split 将执行最佳的整体性能。
function countChar(char: string, string: string): number {
return string.split(char).length - 1
}
countChar('x', 'foo x bar x baz x')
Run Code Online (Sandbox Code Playgroud)
原答案
我知道我参加这里的聚会迟到了,但我很困惑没有人用最基本的方法回答这个问题。社区为此问题提供的大部分答案都是基于迭代的,但所有答案都是基于每个字符在字符串上移动,这并不是真正有效。
当处理包含数千个字符的大字符串时,遍历每个字符来获取出现次数可能会变得相当无关紧要,更不用说代码味道了。以下解决方案利用slice和indexOf值得信赖的传统while循环。这些方法使我们不必遍历每个字符,并将大大加快计算出现次数所需的时间。它们遵循与需要字符串遍历的解析器和词法分析器中类似的逻辑。
与切片一起使用
在这种方法中,我们正在利用slice每场indexOf比赛,我们都会在字符串中移动并消除之前搜索到的药水。每次我们调用时,indexOf它搜索的字符串的大小都会变小。
function countChar (char: string, search: string): number {
let num: number = 0;
let str: string = search;
let pos: number = str.indexOf(char);
while(pos > -1) {
str = str.slice(pos + 1);
pos = str.indexOf(char);
num++;
}
return num;
}
// Call the function
countChar('x', 'foo x bar x baz x') // 3
Run Code Online (Sandbox Code Playgroud)
与位置上的 IndexOf 一起使用
与第一种方法类似slice,但我们不是增加正在搜索的字符串,而是利用方法from中的参数indexOf。
function countChar (char: string, str: string): number {
let num: number = 0;
let pos: number = str.indexOf(char);
while(pos > -1) {
pos = str.indexOf(char, pos + 1);
num++;
}
return num;
}
// Call the function
countChar('x', 'foo x bar x baz x') // 3
Run Code Online (Sandbox Code Playgroud)
就我个人而言,我倾向于第二种方法而不是第一种,但是在处理大字符串和较小尺寸的字符串时,两种方法都很好且性能良好。
小智 5
我发现在一个非常大的字符串中搜索字符的最佳方法(例如,长达1 000 000个字符)就是使用该replace()方法.
window.count_replace = function (str, schar) {
return str.length - str.replace(RegExp(schar), '').length;
};
Run Code Online (Sandbox Code Playgroud)
您可以看到另一个JSPerf套件来测试此方法以及在字符串中查找字符的其他方法.
好的,另一个带有正则表达式的 - 可能不快,但比其他人更短且可读性更好,在我的情况下只是'_'为了计数
key.replace(/[^_]/g,'').length
Run Code Online (Sandbox Code Playgroud)
只需删除所有看起来不像你的字符的东西,但用字符串作为输入看起来不太好
Split 与 RegExp 的性能对比
var i = 0;
var split_start = new Date().getTime();
while (i < 30000) {
"1234,453,123,324".split(",").length -1;
i++;
}
var split_end = new Date().getTime();
var split_time = split_end - split_start;
i= 0;
var reg_start = new Date().getTime();
while (i < 30000) {
("1234,453,123,324".match(/,/g) || []).length;
i++;
}
var reg_end = new Date().getTime();
var reg_time = reg_end - reg_start;
alert ('Split Execution time: ' + split_time + "\n" + 'RegExp Execution time: ' + reg_time + "\n");Run Code Online (Sandbox Code Playgroud)
这是一个类似的解决方案,但它使用 Array.ptototype.reduce
function countCharacters(char, string) {
return string.split('').reduce((acc, ch) => ch === char ? acc + 1: acc, 0)
}
Run Code Online (Sandbox Code Playgroud)
如前所述,String.prototype.split工作速度比快得多String.prototype.replace。
如果你使用 lodash,_.countBy方法会这样做:
_.countBy("abcda")['a'] //2
Run Code Online (Sandbox Code Playgroud)
此方法也适用于数组:
_.countBy(['ab', 'cd', 'ab'])['ab'] //2
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
549443 次 |
| 最近记录: |