Answers:
我已经更新了这个答案。我喜欢更好地使用比赛的想法,但是比较慢:
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
如果您事先知道要搜索的内容,请使用正则表达式文字,否则,可以使用RegExp
构造函数并将该g
标志作为参数传递。
match
返回null
没有结果,因此|| []
我在2009年的原始答案如下。它不必要地创建数组,但是使用拆分速度更快(截至2014年9月)。我很矛盾,如果我真的需要速度,那我毫无疑问会使用拆分,但我更喜欢使用match。
旧答案(从2009年开始):
如果要查找逗号:
(mainStr.split(",").length - 1) //3
如果您正在寻找str
(mainStr.split("str").length - 1) //4
在@Lo的答案和我自己的愚蠢的jsperf测试拆分中,速度至少在Chrome中都领先,但再次创建额外的数组似乎并不理智。
至少有四种方式。最好的选项(由于本地RegEx引擎)也应该是最快的,它位于顶部。jsperf.com目前关闭,否则我将为您提供性能统计信息。
更新:请在此处找到性能测试,并自行运行它们,以贡献您的性能结果。结果的细节将在后面给出。
("this is foo bar".match(/o/g)||[]).length
//>2
"this is foo bar".split("o").length-1
//>2
不建议拆分。资源匮乏。为每个匹配分配“数组”的新实例。不要通过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
搜索单个字符
var stringsearch = "o"
,str = "this is foo bar";
for(var i=count=0; i<str.length; count+=+(stringsearch===str[i++]));
//>count:2
更新:
元素映射和过滤,由于其总体资源预分配而不是使用Pythonian的“生成器”,因此不建议使用
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
分享: 我的要点是,目前使用8种字符计数方法,因此我们可以直接合并并共享我们的想法-只是为了好玩,也许还有一些有趣的基准测试:)
||[]
在做什么,但是这个答案很棒!对于任何人都摸不着头脑,match()
返回null
如果没有找到匹配,并||[]
会返回一个0长度的数组,如果match()
回报率null
,意义length()
将返回0,而不是产生一个错误的类型。
index = -2
,但非常感谢@Augustus
将此功能添加到sting原型:
String.prototype.count=function(c) {
var result = 0, i = 0;
for(i;i<this.length;i++)if(this[i]==c)result++;
return result;
};
用法:
console.log("strings".count("s")); //2
"stringsstringstrings".count("str")
呢?
Google进行了快速搜索(来自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;
}
像这样使用它:
test = 'one,two,three,four'
commas = test.count(',') // returns 3
我发现,搜索很大字符串(例如,长度为1 000 000个字符)中的字符的最佳方法是使用该replace()
方法。
window.count_replace = function (str, schar) {
return str.length - str.replace(RegExp(schar), '').length;
};
您可以看到另一个JSPerf套件来测试此方法以及在字符串中查找字符的其他方法。
您还可以使用以下方式休息字符串并像处理元素数组一样使用它:
const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].filter(l => l === ',').length;
console.log(commas);
要么
const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].reduce((a, c) => c === ',' ? ++a : a, 0);
console.log(commas);
我对可接受的答案进行了一些改进,它允许使用区分大小写/不区分大小写的匹配进行检查,并且是附加到字符串对象的一种方法:
String.prototype.count = function(lit, cis) {
var m = this.toString().match(new RegExp(lit, ((cis) ? "gi" : "g")));
return (m != null) ? m.length : 0;
}
lit
是要搜索的字符串(例如'ex'),而cis是不区分大小写的,默认为false,它将允许选择不区分大小写的匹配项。
'I love StackOverflow.com'
小写字母'o'
,可以使用:
var amount_of_os = 'I love StackOverflow.com'.count('o');
amount_of_os
等于2
。
var amount_of_os = 'I love StackOverflow.com'.count('o', true);
这次amount_of_os
等于3
,因为O
字符串中的大写字母已包含在搜索中。
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");
我发现的最简单方法是...
例-
str = 'mississippi';
function find_occurences(str, char_to_count){
return str.split(char_to_count).length - 1;
}
find_occurences(str, 'i') //outputs 4
我正在做一个需要子字符串计数器的小项目。搜索错误的短语没有给我任何结果,但是在编写自己的实现之后,我偶然发现了这个问题。无论如何,这是我的方式,它可能比这里的大多数慢,但可能对某人有所帮助:
function count_letters() {
var counter = 0;
for (var i = 0; i < input.length; i++) {
var index_of_sub = input.indexOf(input_letter, i);
if (index_of_sub > -1) {
counter++;
i = index_of_sub;
}
}
如果您发现此实现失败或不遵循某些标准,请告诉我!:)
更新 您可能想要替代:
for (var i = 0; i < input.length; i++) {
带有:
for (var i = 0, input_length = input.length; i < input_length; i++) {
有趣的阅读内容讨论了上述内容:http : //www.erichynds.com/blog/javascript-length-property-is-a-stored-value
这是我的解决方案。许多解决方案已经摆在我面前。但我喜欢在这里分享我的观点。
const mainStr = 'str1,str2,str3,str4';
const commaAndStringCounter = (str) => {
const commas = [...str].filter(letter => letter === ',').length;
const numOfStr = str.split(',').length;
return `Commas: ${commas}, String: ${numOfStr}`;
}
// Run the code
console.log(commaAndStringCounter(mainStr)); // Output: Commas: 3, String: 4
最快的方法似乎是通过索引运算符:
function charOccurances (str, char)
{
for (var c = 0, i = 0, len = str.length; i < len; ++i)
{
if (str[i] == char)
{
++c;
}
}
return c;
}
console.log( charOccurances('example/path/script.js', '/') ); // 2
或作为原型函数:
String.prototype.charOccurances = function (char)
{
for (var c = 0, i = 0, len = this.length; i < len; ++i)
{
if (this[i] == char)
{
++c;
}
}
return c;
}
console.log( 'example/path/script.js'.charOccurances('/') ); // 2
以下使用正则表达式测试长度。testex确保您没有连续的16个或更多非逗号字符。如果通过测试,它将继续拆分字符串。计数逗号就像计数令牌减去一一样简单。
var mainStr = "str1,str2,str3,str4";
var testregex = /([^,]{16,})/g;
if (testregex.test(mainStr)) {
alert("values must be separated by commas and each may not exceed 15 characters");
} else {
var strs = mainStr.split(',');
alert("mainStr contains " + strs.length + " substrings separated by commas.");
alert("mainStr contains " + (strs.length-1) + " commas.");
}
我只是使用Node v7.4 对repl.it进行了非常快速和肮脏的测试。对于单个字符,循环的标准最快:
一些代码:
// winner!
function charCount1(s, c) {
let count = 0;
c = c.charAt(0); // we save some time here
for(let i = 0; i < s.length; ++i) {
if(c === s.charAt(i)) {
++count;
}
}
return count;
}
function charCount2(s, c) {
return (s.match(new RegExp(c[0], 'g')) || []).length;
}
function charCount3(s, c) {
let count = 0;
for(ch of s) {
if(c === ch) {
++count;
}
}
return count;
}
function perfIt() {
const s = 'Hello, World!';
const c = 'o';
console.time('charCount1');
for(let i = 0; i < 10000; i++) {
charCount1(s, c);
}
console.timeEnd('charCount1');
console.time('charCount2');
for(let i = 0; i < 10000; i++) {
charCount2(s, c);
}
console.timeEnd('charCount2');
console.time('charCount3');
for(let i = 0; i < 10000; i++) {
charCount2(s, c);
}
console.timeEnd('charCount3');
}
几次运行的结果:
perfIt()
charCount1: 3.843ms
charCount2: 11.614ms
charCount3: 11.470ms
=> undefined
perfIt()
charCount1: 3.006ms
charCount2: 8.193ms
charCount3: 7.941ms
=> undefined
perfIt()
charCount1: 2.539ms
charCount2: 7.496ms
charCount3: 7.601ms
=> undefined
perfIt()
charCount1: 2.654ms
charCount2: 7.540ms
charCount3: 7.424ms
=> undefined
perfIt()
charCount1: 2.950ms
charCount2: 9.445ms
charCount3: 8.589ms
我的解决方案:
function countOcurrences(str, value){
var regExp = new RegExp(value, "gi");
return str.match(regExp) ? str.match(regExp).length : 0;
}
String.prototype.match
回报null
。这意味着不引用具有length
属性的对象。换句话说:String.prototype.match.call('willnotwork', /yesitwill/) === null
如果字符在字符串的开头,则Leo Sauers答案中的第五种方法将失败。例如
var needle ='A',
haystack = 'AbcAbcAbc';
haystack.split('').map( function(e,i){ if(e === needle) return i;} )
.filter(Boolean).length;
将给出2而不是3,因为过滤器功能布尔值将false表示为0。
其他可能的过滤器功能:
haystack.split('').map(function (e, i) {
if (e === needle) return i;
}).filter(function (item) {
return !isNaN(item);
}).length;
我知道这可能是个老问题,但是我为JavaScript的低级初学者提供了一个简单的解决方案。
作为一个初学者,我只能理解该问题的一些解决方案,因此我使用了两个嵌套的FOR循环来对照字符串中的每个其他字符检查每个字符,为找到的等于该字符的每个字符增加一个计数变量。
我创建了一个新的空白对象,其中每个属性键是一个字符,值是每个字符在字符串(计数)中出现的次数。
示例功能:-
function countAllCharacters(str) {
var obj = {};
if(str.length!==0){
for(i=0;i<str.length;i++){
var count = 0;
for(j=0;j<str.length;j++){
if(str[i] === str[j]){
count++;
}
}
if(!obj.hasOwnProperty(str[i])){
obj[str[i]] = count;
}
}
}
return obj;
}
我相信您会发现以下解决方案非常短,非常快,能够处理非常长的字符串,能够支持多个字符搜索,防错并能够处理空字符串搜索。
function substring_count(source_str, search_str, index) {
source_str += "", search_str += "";
var count = -1, index_inc = Math.max(search_str.length, 1);
index = (+index || 0) - index_inc;
do {
++count;
index = source_str.indexOf(search_str, index + index_inc);
} while (~index);
return count;
}
用法示例:
console.log(substring_count("Lorem ipsum dolar un sit amet.", "m "))
function substring_count(source_str, search_str, index) {
source_str += "", search_str += "";
var count = -1, index_inc = Math.max(search_str.length, 1);
index = (+index || 0) - index_inc;
do {
++count;
index = source_str.indexOf(search_str, index + index_inc);
} while (~index);
return count;
}
上面的代码修复了Jakub Wawszczyk的主要性能错误,即使在indexOf表示不存在任何匹配且其版本本身不起作用,因为他忘记提供函数输入参数后,该代码仍会继续寻找匹配项。
该函数将字符串str作为参数,并对字符串中每个唯一字符的出现进行计数。结果进入每个字符的键-值对。
var charFoundMap = {};//object defined
for (var i = 0; i < str.length; i++) {
if(!charFoundMap[ str[i] ]) {
charFoundMap[ str[i] ]=1;
}
else
charFoundMap[ str[i] ] +=1;
//if object does not contain this
}
return charFoundMap;
}