how to convert this C# code snippet to Javascript [duplicate] - javascript

This question already has answers here:
Repeat String - Javascript [duplicate]
(30 answers)
Closed 7 years ago.
I need to understand how Javascript handles the new string object just like in the C# code below
var UpperBound = 14;
for (int i = 0; i < UpperBound; i++) {
Console.WriteLine(new string('*', i));
}
Console.ReadLine();
This was how i did it in Javascript:
var upperBound = 14;
for(var i=0;i<upperBound;i++){
console.log(new string("*", i));
}
Am a newbie in programming and i started off with javascript so if i appear dumb by asking this question pls pardon and assist me by explaining.. thanks

There is no equivalent for new string("*", i) in JS. You need to do repetition yourself.
A handy hack is Array(i + 1).join("*"), but it is not very efficient I don't think, as it needs to construct the array. The best way is probably to loop and concatenate.

Your code is good except for this part:
new string("*", i)
It is incorrect syntax for JS. You need to create string another way.
That's how you should create a string with repeating character in JavaScript.
I should note that String.prototype.repeat is a part of ECMAScript 6.
var upperBound = 14;
for(var i=0;i<upperBound;i++)
{
document.write('*'.repeat(i));
document.write("<br/>");
}
Before it, you should use another approach like making this string manually in a for-loop like this:
function repeatString(ch, t)
{
var res = '';
for (var i = 0; i < t; i++) res += ch;
return res;
}
var upperBound = 14;
for(var i=0;i<upperBound;i++)
{
document.write(repeatString('*', i));
document.write("<br/>");
}
There are some other approaches and hacks. You can read this StackOverflow topic on it.
I suggest you to read a good tutorial on JavaScript before trying to write it.
C# and JavaScript are very different languages in all terms. You cannot just take a C# code, change a syntax and think that it will work.

I would like to combine two solutions, so (the best option is to use es6-shim) here is a polyfill (borrowed from here)
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null) {
throw new TypeError('can\'t convert ' + this + ' to object');
}
var str = '' + this;
count = +count;
if (count != count) {
count = 0;
}
if (count < 0) {
throw new RangeError('repeat count must be non-negative');
}
if (count == Infinity) {
throw new RangeError('repeat count must be less than infinity');
}
count = Math.floor(count);
if (str.length == 0 || count == 0) {
return '';
}
// Ensuring count is a 31-bit integer allows us to heavily optimize the
// main part. But anyway, most current (August 2014) browsers can't handle
// strings 1 << 28 chars or longer, so:
if (str.length * count >= 1 << 28) {
throw new RangeError('repeat count must not overflow maximum string size');
}
var rpt = '';
for (;;) {
if ((count & 1) == 1) {
rpt += str;
}
count >>>= 1;
if (count == 0) {
break;
}
str += str;
}
return rpt;
}
}
And the usage:
var upperBound = 14;
for(var i=0;i<upperBound;i++){
console.log("*".repeat(i));
}

Related

Reverse a string using two-pointer method in JS

I am trying to reverse a string. I am aware of .reverse function and other methods in Js to do so, but i wanted to do it this two-pointer method.
The problem is the string is not getting updated. Is there anything i am not aware of strings. Whats wrong here ?
function reverseString(s) {
let lengthOfStr = 0;
if ((s.length - 1) % 2 == 0) {
lengthOfStr = (s.length - 1) / 2
} else {
lengthOfStr = ((s.length - 1) / 2) + 1;
}
let strLengthLast = s.length - 1;
for (let i = 0; i <= lengthOfStr; i++) {
let pt1 = s[i];
let pt2 = s[strLengthLast];
s[i] = pt2;
s[strLengthLast] = pt1;
console.log('----', s[i], s[strLengthLast]);
strLengthLast--;
}
return s;
}
console.log(reverseString('hello'));
Unlike in C, strings in JavaScript are immutable, so you can't update them by indexing into them. Example:
let s = 'abc';
s[1] = 'd';
console.log(s); // prints abc, not adc
You'd need to do something more long-winded in place of s[i] = pt2;, like s = s.substring(0, i) + pt2 + s.substring(i + 1);, and similarly for s[strLengthLast] = pt1; (or combine them into one expression with 3 calls to substring).
I'm not sure why it doesnt update the string, but if you handle the replacement as an array/list it works as follows:
function reverseString(s) {
let lengthOfStr = 0;
sSplit = s.split("");
if ((s.length - 1) % 2 === 0) {
lengthOfStr = (s.length - 1) / 2
}
else {
lengthOfStr = ((s.length - 1) / 2) + 1;
}
let strLengthLast = s.length - 1;
for (let i = 0; i <= lengthOfStr; i++) {
let pt1 = sSplit[i];
let pt2 = sSplit[strLengthLast];
sSplit[i] = pt2;
sSplit[strLengthLast] = pt1;
console.log('----', sSplit[i], sSplit[strLengthLast],sSplit);
strLengthLast--;
}
return sSplit.join("");
}
console.log(reverseString('Hello'));
returns: Hello => olleH
As covered in comment, answers and documentation, strings are immutable in JavaScript.
The ability to apparently assign a property value to a primitive string value results from early JavaScript engine design that temporarily created a String object from primitive strings when calling a String.prototype method on the primitive. While assigning a property to the temporary object didn't error, it was useless since the object was discarded between calling the String method and resuming execution of user code.
The good news is that this has been fixed. Putting
"use strict";
at the beginning of a JavaScript file or function body causes the compiler to generate a syntax error that primitive string "properties" are read-only.
There are many ways of writing a function to reverse strings without calling String.prototype.reverse. Here's another example
function strReverse(str) {
"use strict";
let rev = [];
for( let i = str.length; i--;) {
rev.push(str[i]);
}
return rev.join('');
}
console.log( strReverse("Yellow") );
console.log( strReverse("").length);
I tried that way, hopefully might be helpful for someone.
const input = 'hello'; /*input data*/
const inputArray = [...input]; /*convert input data to char array*/
function reverseString(inputArray) {
let i = 0;
let j = inputArray.length -1 ;
while(i < j ) {
const temp = inputArray[i];
inputArray[i] = inputArray[j];
inputArray[j] = temp;
i++;
j--;
}
};
reverseString(inputArray);
console.log(inputArray)
const finalResult = inputArray.join("");
console.log(finalResult);
Thanks.

Converting a 64 bit HEX to Decimal Floating-Pointt in Javascript

So basically I have a couple of numbers that come out as HEX values in the form of "3FF0000000000000" and I want to get float values of out these, pretty much like in here So in this particular case I'd expect "20.000000000000000" as a result - which I'll later trim to only 5 decimals, but that should be easy enough.
I've tried a couple of solutions but unfortunately I know too little about conversions (and javascript aswell) to know exactly what I might be doing wrong.
The latest try looks something like this:
const hexToFloat64 = (hex) => {
var int32 = [],
float64;
if (hex.length > 4) {
var high = hex.substr(0, 8),
low = hex.substr(8, 8);
int32.push(parseInt(high, 16), parseInt(low, 16));
}
var uint32 = new Uint32Array(int32);
float64 = new Float64Array(uint32.buffer);
var returnValue = float64[0];
return returnValue;
};
Much obliged!
This is NOT an answer to your exact problem. It IS a solution to decode the hex. Thats all i am doing here. I have no context to solve your problem.
function convHexStringToString(ss) {
// ss length must be even (or 0) when passed to this function
var s = "";
var p;
if (ss.length > 0) {
if (ss.length % 2 == 0) {
var l = Math.floor(ss.length / 2); // floor must never have to do work
for (var i = 0; i < l; i++) {
var i2 = i * 2;
if (ss.charAt(i2) != "0") {
p = ss.charAt(i2) + ss.charAt((i2) + 1);
}
else {
p = ss.charAt((i2) + 1);
}
d = parseInt(p,16);
s += String.fromCharCode(d);
}
}
}
return s;
}

Iterate two string arrays simultaneously using javascript

I am new to javascript. Now, I want to make comparison of two website pair by iterating two string array as a pair the same time. These two string array's length are the same. I have searched for sites but didn't find the way to do in javascript. For example, in python, people can do this by using zip(), referencing from
How to merge lists into a list of tuples?.
However, in javascript, I try to something similar to that, but it will iterate over the second list every time it iterate over the element of first list, which is not want I wanted.
codes not what I expected
var FistList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
var SecondList=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat'];
FirstList.forEach(firstListItem => {
SecondList.forEach(secondListItem => {
//do comparison for these two websites....
});
});
What I expect is to do comparison pair by pair, which is =>
first loop: do comparison of 'https://test1-1/travel' and 'https://test1-2/travel'
second loop: do comparison of 'https://test1-1/cook' and 'https://test1-2/cook'
third loop: do comparison of 'https://test1-1/eat' and 'https://test1-2/eat'
I searched for a whole day but cannot find the way to do in javascript. Please advise. Thanks in advance!
If all you want is to compare values in same position of each array just use the index argument of forEach to reference array element in other array
var FirstList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
var SecondList=['https://test1-2/travel','https://test1-1/cook','https://test1-1/eat'];
FirstList.forEach((str, i) => console.log(str === SecondList[i]))
I think a very similar question was already answered here: How to compare arrays in JavaScript?
Accepted answer (https://stackoverflow.com/a/14853974/1842205) describes in depth how you could achieve such a goal.
JavaScript lacks of such a feature like mentioned zip() method from Python. But we have something like prototyping in JS :). And you can create 2D array like below:
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[length-1 - i] = createArray.apply(this, args);
}
return arr;
}
Array.prototype.zip = function (secondArr) {
let result = createArray(secondArr.length, 2);
for (let i = 0; i < this.length; i++) {
result[i][0] = this[i];
result[i][1] = secondArr[i];
}
return result;
};
// usage
var FistList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
var SecondList=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat'];
console.log(JSON.stringify(FistList.zip(SecondList)));
I like the OP's idea of making a more functional solution using zip, which can be home-rolled or reused from loadash or underscore.
const firstArray=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat'];
const secondArray=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat'];
const zipped = _.zip(firstArray, secondArray)
const compared = zipped.map(([first, second]) => first === second)
console.log(compared)
// reduce the pairwise comparison to a single bool with every()
// depends on requirements, but probably true iff every comparison is true
const arraysMatch = compared.every(e => e)
console.log(arraysMatch)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
Note that more functional solutions often involve the creation of some intermediate arrays (aka garbage) which is fine for small inputs.
I think the purpose of a forEach loop is to iterate over 1 list only. I would consider using a generic for loop to serve this purpose.
EDIT: I edited the code, and added a string prototype function to calculate the Levenstein distance between 2 strings. It's not rigid to detect for an edit in the exact spot your strings are changed in the examples. But I expect the examples are probably not totally reflective of your real data anyway, so instead of giving you some questionable regex, I'm giving you Levenstein and hope you understand it doesn't care where the difference is, it just cares how much has changed. In the example I only allow 1 character or less of difference: if (diff <= 1) {
//Define a string function for Levenstein Edit Distance
//call it "distancefrom" for clarity
String.prototype.distancefrom = function(string) {
var a = this, b = string + "", m = [], i, j, min = Math.min;
if (!(a && b)) return (b || a).length;
for (i = 0; i <= b.length; m[i] = [i++]);
for (j = 0; j <= a.length; m[0][j] = j++);
for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
m[i][j] = b.charAt(i - 1) == a.charAt(j - 1)
? m[i - 1][j - 1]
: m[i][j] = min(
m[i - 1][j - 1] + 1,
min(m[i][j - 1] + 1, m[i - 1 ][j] + 1))
}
}
return m[b.length][a.length];
}
//Your Code
var FirstList=['https://test1-1/travel','https://test1-1/cook','https://test1-1/eat', 'https://waffles.domain/syrup', 'http://pancakes.webpresence/butter'];
var SecondList=['https://test1-2/travel','https://test1-2/cook','https://test1-2/eat', 'https://waffles.domain/syrups', 'https://pancakes.webpresence/buttery'];
for (let i=0; i < FirstList.length; i++) {
let diff = FirstList[i].distancefrom(SecondList[i]);
console.log('"'+FirstList[i]+'" is different than "'+SecondList[i]+'" by '+diff+' characters');
if (diff <= 1) {
console.log('Since its less than 1 character of difference, it would technically Pass our test.');
} else {
console.log('Since its more than 1 character of difference, it would Fail our test!');
}
console.log('-----------------');
}
References:
Levenstin Gist by scottgelin on GitHub

Accessing a counter in a variable name in Javascript (code inside)

I am looking to do something very similar to the following PHP code but in javascipt:
for ($weenumber = 1; $weenumber <= 30; $weenumber++)
{
$weenumber = str_pad($weenumber, 2, "0", STR_PAD_LEFT);
echo $_POST["entry{$weenumber}_cash"];
}
Basically accessing the loop number padded with a trailing 0 if less than 10 but I dont know the syntax in JS to do this :(
Sorry for noob style question
I think that you mean a leading zero rather than a trailing zero...
You can for example use the conditional operator:
(n < 10 ? '0' : '') + n
You could also implement a general purpose function:
function padLeft(str, len, ch) {
while (str.length < len) str = ch + str;
return str;
}
To access an object property by name in Javascript you use brackets. Example:
var value = obj['entry' + (n < 10 ? '0' : '') + n + '_cash'];
If n contains 4, this will be the same as obj.entry04_cash.
Whether or not there's a specific function to do this, if you know how to use an if clause, and you know how to perform string concatentation (using the + operator if you didn't), then you should be able to easily roll you own version of str_pad by hand (which works for numbers below 100).
Think about the cases involved (there are only two) and what you need to output in either case.
This is the code you should use:
for(var i=0; i<30; i++){
document.writeln(i<10 ? "0"+i : i);
}
change document.writeln() with any function you want to handle the data
for (weenumber = 1; weenumber <= 30; weenumber++) {
weenumber = str_pad(weenumber, 2, "0", STR_PAD_LEFT);
}
For the str_pad() function, you can use PHPJS library:
http://phpjs.org/functions/str_pad:525
This library will also ease transition from php to javascript for you. Check it out.
for(var i=0; i<30; i++)
{
var index = i;
if(i<10) index = "0" + index
var elem = document.getElementById("entry"+index);
}
var someArray = [/*...*/];
for (var i= 1;i<= 30;i++)
{
var weenumber = i+"";
for(var j=weenumber.length;j<2;j++)
weenumber = "0" + weenumber;
var key = "entry" + weenumber + "_cash";
document.write(someArray[key]);
}
Here's a function you can use for zeropadding:
function zeroPad(nr,base){
var len = (String(base).length - String(nr).length)+1;
return len > 0? new Array(len).join('0')+nr : nr;
}
//usage
alert(zeroPad(3,10)); //=> 03
or extend the Number prototype
Number.prototype.zeroPad = Number.prototype.zeroPad ||
function(base){
var nr = this, len = (String(base).length - String(nr).length)+1;
return len > 0? new Array(len).join('0')+nr : nr;
};
//usage
var num = 1;
alert(num.zeroPad(100)); //=> 001
Now for the variable name part: if it's a global variable (not advisable) that variable is a property of the global object, in a browser that's window. You can get a variable by its dynamic name using the equivalent of: window['myvariable'+myJustResolvedNumericValue]. Within an object (instance) you can use the same bracket notation: myObject['myvariable'+myJustResolvedNumericValue].
Using this information, in javascript your function could look like:
for (var weenumber = 1; weenumber <= 30; weenumber++)
{
// execute something using the variable that uses the counter in the
// variable name as parameter
executeSomeFunction(window['entry'+weenumber.padLeft(10) + '_cash']);
}

Count the number of occurrences of a character in a string in Javascript

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";
I want to find the count of comma , character, which is 3. And the count of individual strings after the split along comma, which is 4.
I also need to validate that each of the strings i.e str1 or str2 or str3 or str4 should not exceed, say, 15 characters.
I have updated this answer. I like the idea of using a match better, but it is slower:
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
Use a regular expression literal if you know what you are searching for beforehand, if not you can use the RegExp constructor, and pass in the g flag as an argument.
match returns null with no results thus the || []
The original answer I made in 2009 is below. It creates an array unnecessarily, but using a split is faster (as of September 2014). I'm ambivalent, if I really needed the speed there would be no question that I would use a split, but I would prefer to use match.
Old answer (from 2009):
If you're looking for the commas:
(mainStr.split(",").length - 1) //3
If you're looking for the str
(mainStr.split("str").length - 1) //4
Both in #Lo's answer and in my own silly performance test split comes ahead in speed, at least in Chrome, but again creating the extra array just doesn't seem sane.
There are at least five ways. The best option, which should also be the fastest (owing to the native RegEx engine) is placed at the top.
Method 1
("this is foo bar".match(/o/g)||[]).length;
// returns 2
Method 2
"this is foo bar".split("o").length - 1;
// returns 2
Split not recommended as it is resource hungry. It allocates new instances of 'Array' for each match. Don't try it for a >100MB file via FileReader. You can observe the exact resource usage using Chrome's profiler option.
Method 3
var stringsearch = "o"
,str = "this is foo bar";
for(var count=-1,index=-2; index != -1; count++,index=str.indexOf(stringsearch,index+1) );
// returns 2
Method 4
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++]));
// returns 2
Method 5
Element mapping and filtering. This is 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
// returns 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 :)
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
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
A quick Google search got this (from 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;
}
Use it like this:
test = 'one,two,three,four'
commas = test.count(',') // returns 3
You can also rest your string and work with it like an array of elements using
Array.prototype.filter()
const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].filter(l => l === ',').length;
console.log(commas);
Or
Array.prototype.reduce()
const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].reduce((a, c) => c === ',' ? ++a : a, 0);
console.log(commas);
UPDATE: This might be simple, but it is not the fastest. See benchmarks below.
It's amazing that in 13 years, this answer hasn't shown up. Intuitively, it seems like it should be fastest:
const s = "The quick brown fox jumps over the lazy dog.";
const oCount = s.length - s.replaceAll('o', '').length;
If there are only two kinds of character in the string, then this is faster still:
const s = "001101001";
const oneCount = s.replaceAll('0', '').length;
BENCHMARKS
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})`);
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)
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.
If you are using lodash, the _.countBy method will do this:
_.countBy("abcda")['a'] //2
This method also work with array:
_.countBy(['ab', 'cd', 'ab'])['ab'] //2
ok, an other one with regexp - probably not fast, but short and better readable then others, in my case just '_' to count
key.replace(/[^_]/g,'').length
just remove everything that does not look like your char
but it does not look nice with a string as input
I have found that the best approach to search for a character in a very large string (that is 1 000 000 characters long, for example) is to use the replace() method.
window.count_replace = function (str, schar) {
return str.length - str.replace(RegExp(schar), '').length;
};
You can see yet another JSPerf suite to test this method along with other methods of finding a character in a string.
Performance of Split vs 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");
I made a slight improvement on the accepted answer, it allows to check with case-sensitive/case-insensitive matching, and is a method attached to the string object:
String.prototype.count = function(lit, cis) {
var m = this.toString().match(new RegExp(lit, ((cis) ? "gi" : "g")));
return (m != null) ? m.length : 0;
}
lit is the string to search for ( such as 'ex' ), and cis is case-insensitivity, defaulted to false, it will allow for choice of case insensitive matches.
To search the string 'I love StackOverflow.com' for the lower-case letter 'o', you would use:
var amount_of_os = 'I love StackOverflow.com'.count('o');
amount_of_os would be equal to 2.
If we were to search the same string again using case-insensitive matching, you would use:
var amount_of_os = 'I love StackOverflow.com'.count('o', true);
This time, amount_of_os would be equal to 3, since the capital O from the string gets included in the search.
Easiest way i found out...
Example-
str = 'mississippi';
function find_occurences(str, char_to_count){
return str.split(char_to_count).length - 1;
}
find_occurences(str, 'i') //outputs 4
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
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.301ms
charCount2: 11.652ms
charCount3: 174.043ms
undefined
perfIt()
charCount1: 2.110ms
charCount2: 11.931ms
charCount3: 177.743ms
undefined
perfIt()
charCount1: 2.074ms
charCount2: 11.738ms
charCount3: 152.611ms
undefined
perfIt()
charCount1: 2.076ms
charCount2: 11.685ms
charCount3: 154.757ms
undefined
Update 2021-Feb-10: Fixed typo in repl.it demo
Update 2020-Oct-24: Still the case with Node.js 12 (play with it yourself here)
UPDATE 06/10/2022
So I ran various perf tests and if your use case allows it, it seems that using split is going to perform the best overall.
function countChar(char: string, string: string): number {
return string.split(char).length - 1
}
countChar('x', 'foo x bar x baz x')
I know I am late to the party here but I was rather baffled no one answered this with the most basic of approaches. A large portion of the answers provided by the community for this question are iteration based but all are moving over strings on a per-character basis which is not really efficient.
When dealing with a large string that contains thousands of characters walking over each character to get the occurance count can become rather extraneous not to mention a code-smell. The below solutions take advantage of slice, indexOf and the trusted traditional while loop. These approaches prevent us having to walk over each character and will greatly speed up the time it takes to count occurances. These follow similar logic to that you'd find in parsers and lexical analyzers that require string walks.
Using with Slice
In this approach we are leveraging slice and with every indexOf match we will move our way through the string and eliminate the previous searched potions. Each time we call indexOf the size of the string it searches will be smaller.
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
Using with IndexOf from position
Similar to the first approach using slice but instead of augmenting the string we are searching it will leverage the from parameter in indexOf method.
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
Personally, I go for the second approach over the first, but both are fine and performant when dealing with large strings but also smaller sized ones too.
s = 'dir/dir/dir/dir/'
for(i=l=0;i<s.length;i++)
if(s[i] == '/')
l++
I was working on a small project that required a sub-string counter. Searching for the wrong phrases provided me with no results, however after writing my own implementation I have stumbled upon this question. Anyway, here is my way, it is probably slower than most here but might be helpful to someone:
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;
}
}
http://jsfiddle.net/5ZzHt/1/
Please let me know if you find this implementation to fail or do not follow some standards! :)
UPDATE
You may want to substitute:
for (var i = 0; i < input.length; i++) {
With:
for (var i = 0, input_length = input.length; i < input_length; i++) {
Interesting read discussing the above:
http://www.erichynds.com/blog/javascript-length-property-is-a-stored-value
What about string.split(desiredCharecter).length-1
Example:
var str = "hellow how is life";
var len = str.split("h").length-1; will give count 2 for character "h" in the above string;
The fastest method seems to be via the index operator:
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
Or as a prototype function:
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
function len(text,char){
return text.innerText.split(string).length
}
console.log(len("str1,str2,str3,str4",","))
This is a very short function.
The following uses a regular expression to test the length. testex ensures you don't have 16 or greater consecutive non-comma characters. If it passes the test, then it proceeds to split the string. counting the commas is as simple as counting the tokens minus one.
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.");
}
I'm using Node.js v.6.0.0 and the fastest is the one with index (the 3rd method in Lo Sauer's answer).
The second is:
function count(s, c) {
var n = 0;
for (let x of s) {
if (x == c)
n++;
}
return n;
}
And there is:
function character_count(string, char, ptr = 0, count = 0) {
while (ptr = string.indexOf(char, ptr) + 1) {count ++}
return count
}
Works with integers too!
Here's one just as fast as the split() and the replace methods, which are a tiny bit faster than the regex method (in Chrome and Firefox both).
let num = 0;
let str = "str1,str2,str3,str4";
//Note: Pre-calculating `.length` is an optimization;
//otherwise, it recalculates it every loop iteration.
let len = str.length;
//Note: Don't use a `for (... of ...)` loop, it's slow!
for (let charIndex = 0; charIndex < len; ++charIndex) {
if (str[charIndex] === ',') {
++num;
}
}
var mainStr = "str1,str2,str3,str4";
var splitStr = mainStr.split(",").length - 1; // subtracting 1 is important!
alert(splitStr);
Splitting into an array gives us a number of elements, which will always be 1 more than the number of instances of the character. This may not be the most memory efficient, but if your input is always going to be small, this is a straight-forward and easy to understand way to do it.
If you need to parse very large strings (greater than a few hundred characters), or if this is in a core loop that processes large volumes of data, I would recommend a different strategy.
String.prototype.reduce = Array.prototype.reduce;
String.prototype.count = function(c) {
return this.reduce(((n, x) => n + (x === c ? 1 : 0)), 0)
};
const n = "bugs bunny was here".count("b")
console.log(n)
Similar to the prototype based above, but does not allocate an array for the string. Allocation is the problem of nearly every version above, except the loop variants. This avoids loop code, reusing the browser implemented Array.reduce function.
My solution:
function countOcurrences(str, value){
var regExp = new RegExp(value, "gi");
return str.match(regExp) ? str.match(regExp).length : 0;
}
I know this might be an old question but I have a simple solution for low-level beginners in JavaScript.
As a beginner, I could only understand some of the solutions to this question so I used two nested FOR loops to check each character against every other character in the string, incrementing a count variable for each character found that equals that character.
I created a new blank object where each property key is a character and the value is how many times each character appeared in the string(count).
Example function:-
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;
}

Categories