I need to count the number of occurrences of a character in a string.
For example, suppose my string contains:
var mainStr = \"str1,str2,str3,str4\";
There are at least four ways. The best option, which should also be the fastest -owing to the native RegEx engine -, is placed at the top. jsperf.com is currently down, otherwise I would provide you with performance statistics.
Update: Please, find the performance tests here, and run them yourselves, so as to contribute your performance results. The specifics of the results will be given later.
("this is foo bar".match(/o/g)||[]).length
//>2
"this is foo bar".split("o").length-1
//>2
split not recommended. Resource hungry. Allocates new instances of 'Array' for each match. Don't try that for a >100MB file via FileReader. You can actually easily observe the EXACT resource usage using Chrome's profiler option.
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
searching for a single character
var stringsearch = "o"
,str = "this is foo bar";
for(var i=count=0; i<str.length; count+=+(stringsearch===str[i++]));
//>count:2
Update:
element mapping and filtering, not recommended due to its overall resource preallocation rather than using Pythonian 'generators'
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
Share: I made this gist, with currently 8 methods of character-counting, so we can directly pool and share our ideas - just for fun, and perhaps some interesting benchmarks :)
https://gist.github.com/2757250
Simply, use the split to find out the number of occurrences of a character in a string.
mainStr.split(',').length
// gives 4 which is the number of strings after splitting using delimiter comma
mainStr.split(',').length - 1
// gives 3 which is the count of comma
Here is my solution. Lots of solution already posted before me. But I love to share my view here.
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
Here you find my REPL
Here is a similar solution, but it uses Array.prototype.reduce
function countCharacters(char, string) {
return string.split('').reduce((acc, ch) => ch === char ? acc + 1: acc, 0)
}
As was mentioned, String.prototype.split
works much faster than String.prototype.replace
.
Add this function to sting prototype :
String.prototype.count=function(c) {
var result = 0, i = 0;
for(i;i<this.length;i++)if(this[i]==c)result++;
return result;
};
usage:
console.log("strings".count("s")); //2
I just did a very quick and dirty test on repl.it using Node v7.4. For a single character, the standard for loop is quickest:
Some code:
// 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');
}
Results from a few runs:
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
Update 2020-Oct-24: Still the case with Node.js 12 (play with it yourself here)