The answer should be valid for any given input - javascript

Write a function which takes a sentence as an input and output a sorted sentence.
1.Each character of the word should be arranged in alphabetical order
Words should be arranged in ascending order depending on its character count
Note: - Word only can have lowercase letters
Example :
Inputs str = "she lives with him in a small apartment"
Output = "a in ehs him hitw eilsv allms aaemnprtt"
function makeAlphabetSentenceSort(str) {
var word = str.split(' ');
for (var j = 0; j < word.length; j++) {
word[j] = word[j].split('').sort().join('');
}
for (var h = 0; h < word.length - 1; h++) {
for (var i = 0; i < word.length - h - 1; i++) {
if (String(word[i]).length > String(word[i + 1]).length) {
var temp = word[i];
word[i] = word[i + 1];
word[i + 1] = temp;
}
}
}
return word.join(' ');
}
console.log(makeAlphabetSentenceSort("she lives with him in a small apartment"));
ERROR message is "The answer should be valid for any given input."

Upon further reflection, it's clear that their challenge isn't following their own rules. It clearly states:
Word only can have lowercase letters
Yet, it runs this through the code (with punctuation):
he was curious about how it would taste, so he took a small bite.
To make matters worse, it expects the following output, which places how before saw, even though how appears after saw:
a eh it os eh how asw koot .beit allms dlouw abotu ,aestt ciorsuu
So, to be able to pass this challenge, you're also going to need to swap words of the same length with each other.
NodeJS Solution
The following produces the correct results in NodeJS, but not in the browser, in fact, sort() gave me different results in different browsers!
function makeAlphabetSentenceSort(str) {
var word = str.split(' ');
for (var j = 0; j < word.length; j++) {
word[j] = word[j].split('').sort().join('');
}
return word.sort((a, b) => a.length - b.length).join(' ');
}
console.log(makeAlphabetSentenceSort('he was curious about how it would taste, so he took a small bite.'));
I then read about why sort is so unreliable, and this article is a great resource, unfortunately, the solution in it provides reliable results, but not in the way this challenge expects it.
https://medium.com/#fsufitch/is-javascript-array-sort-stable-46b90822543f
Challenge
http://ccc.fidenz.com/en/challenges/challenges/challenge--86
Takeaway
This is a horribly designed challenge, you really should focus your efforts on a better website to practice programming, such as HackerRank, instead of this hodgepodge mess.

Related

Split long words into equal-length pieces

How can I use JavaScript to split extremely long words? I am not looking for a CSS solution like word-break: break-all. The goal is to insert spaces in long words to break them into smaller pieces. The solution should be as fast as possible, since it will be called thousands of times in a few seconds.
Example how the solution should work:
splitString("This is an exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxample string.");
=> This is an exxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxxxxxample string.
splitString("AnotherExammmmmmmmmmmpleeeeeeeeeeeeeeeee");
=> AnotherExammmmmm mmmmmpleeeeeee eeeeeeeeee
Any words that are too long are split with a space character.
It would be even better if the resulting pieces were of roughly equal length.
Since you asked for performance, I compared a regex approach:
function splitString(str, length) {
var regex = new RegExp("/(\w{" + length + "})(?=\w)/g");
return str.replace(regex, "$1 ");
}
with this relatively simple handmade solution:
function splitString(str, length) {
var words = str.split(" ");
for (var j = 0; j < words.length; j++) {
var l = words[j].length;
if (l > length) {
var result = [], i = 0;
while (i < l) {
result.push(words[j].substr(i, length))
i += length;
}
words[j] = result.join(" ");
}
}
return words.join(" ");
}
JsPerf says that the regex version is roughly 8% faster on my machine (Mac Opera16). As this is also more concise, I would go for it.
While this does nothing to ensure that the pieces are of equal length, it will ensure no word in your string is longer than 40 characters.
'This is an exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxample string.'
.replace(/(\w{40})(?=\w)/g, '$1 ');
>> 'This is an exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xample string.'
A "word" is defined here as a consecutive string of letters, numbers, and underscores. If you wish to apply a different definition of "word" (e.g., if your "words" can contain Unicode characters), you will need to swap \w for the character class of your choice.
Here's what I came up with:
http://jsfiddle.net/KyleMuir/czBZz/
function splitString(value) {
var tooLongDeterminer = 12;
var words = value.split(' ');
for (var i = words.length - 1; i >= 0; i--) {
if (words[i].length > tooLongDeterminer) {
var split = words[i];
var tempArray = new Array();
while (split != '') {
var word = splitWord(split, tooLongDeterminer);
tempArray.push(word);
split = split.replace(word, '');
}
words.splice(i, 1, tempArray.join(' '));
}
}
return words.join(' ');
}
function splitWord(word, length) {
return word.substring(0, length);
}
console.log(splitString("This is an exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxample string."));
console.log(splitString("AnotherExammmmmmmmmmmpleeeeeeeeeeeeeeeee"));
Note: this is recursive (and only tested on chrome) so may or may not suit your purposes but the output from the above console.logs are as follows:
AnotherExamm mmmmmmmmmple eeeeeeeeeeee eeee
This is an exxxxxxxxxxx xxxxxxxxxxxx xxxxxxxxxxxx xxxxxample string.
Hope this helps and thanks for the challenge :)

Intense loop freezing browser; how to make server do it?

Basic outline; I am retrieving ~100 Facebook statuses, and running a search of these posts to check if it contains one of ~20 search terms. When I try to run it in the browser it locks up, which makes me apprehensive to try and run this on the client side.
What would be the easiest way to have the server run this operation and return the results? Can I do it in Python? Here is the loop, for reference.
function Filter() {
console.log("running Filter")
//loop through fbObj.posts
for (i = 0, l = fbObj.length; i < l; i++){
var post = fbObj[i].post
console.log("Checking " + post + " for search terms")
//loop through searchTerms
for (j = 0; j<searchTermObj.length; j= j++) {
searchTerm_variants = searchTermObj[j].words
for (x = 0; x < searchTerm_variants.length; x++){
if (post.indexOf(searchTerm_variants[x]) !== 0){
foundPosts[i] = {}
foundPosts[i] = fbObj[i]
}
}
}
console.log(foundPosts)
}
}
You have an error in your code that might explain the lockup :
//loop through searchTerms
for (j = 0; j<searchTermObj.length; j= j++) {
j is never incremented (so it is always 0) :
j++ increments j, but evaluates to j which is assigned to j. So it's a null operation.
Therefore your code gets stuck in the loop.
Have you thought of using worker threads to do this on the client? However this might be available only in the latest builds of various browsers?
https://developer.mozilla.org/en-US/docs/DOM/Worker
You could build an all-encompassing regex like this, I think:
var regexWords = [], variants;
for (var i = 0; i < searchTermObj.length; ++i) {
variants = searchTermObj[i].words;
for (var j = 0; j < variants.length; ++j)
regexWords.push(variants[j]);
}
var regex = new RegExp(regexWords.join("|"));
Then you can test each post like this:
for (i = 0, l = fbObj.length; i < l; i++){
var post = fbObj[i].post
if (regex.test(post)) {
// found a naughty word in the post
}
}
Now this works so long as your word lists are just alphabetic words, with no funny characters like "*" or "." in them. You could still make this work if they did contain special characters, but it'd be a little more complex.
Doing it with a big regex like that allows the regex engine to employ smart sub-linear searching techniques, so that each post only needs to be searched once. It still may not be extremely fast.

Javascript: matching a dynamic string against an array

I'm attempting to teach myself javascript. I chose something I assumed was simple, but ran into problems relatively quickly.
I'm attempting to search a string for another string given by the user.
My code so far is:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = [];
var one = 0;
var two = 0;
var k = 0;
var sourceSearch = function(text) {
for(i = 0; i < source.length; i++) { //for each character in the source
if(source[i] === searchString[0]) { //if a character in source matches the first element in the users input
one = source.indexOf(i); //confused from here on
for(p = searchString.length; p > 0; p--) {
}
}
}
};
sourceSearch(searchString);
My idea was:
check to see if the first loop finds a character that matches the first character in the user input
if it matches, check to see if the next X characters after the first match the next X characters in the source string
if they all match, push them to the hits array
My problem: I have no idea how to iterate along the arrays without nesting quite a few if statements, and even then, that wouldn't be sufficient, considering I want the program to work with any input.
Any ideas would be helpful. Thanks very much in advance.
Note: There are a few un-used variables from ideas I was testing, but I couldn't make them work.
You can try:
if (source.indexOf(searchString) !== -1) {
// Match!
}
else
{
//No Match!
}
As the other answers so far point out, JavaScript strings have an indexOf function that does what you want. If you want to see how it's done "by hand", you can modify your function like this:
var sourceSearch = function(text) {
var i, j, ok; // always declare your local variables. globals are evil!
// for each start position
for(i = 0; i < source.length; i++) {
ok = true;
// check for a match
for (j = searchString.length - 1; ok && j >= 0; --j) {
ok = source[i + j] === searchString[j];
}
if (ok) {
// searchString found starting at index i in source
}
}
};
This function will find all positions in source at which searchString was found. (Of course, you could break out of the loop on the first success.) The logic is to use the outer loop to advance to each candidate start position in source and use the inner loop to test whether that position actually is the position of a match to searchString.
This is not the best algorithm for searching strings. The built-in algorithm is much faster (both because it is a better algorithm and because it is native code).
to follow your approach, you can just play with 2 indexes:
var sourceSearch = function(text) {
j = 0;
for(i = 0; i < source.length; i++) {
if(source[i] === text[j]) {
j++;
} else {
j = 0;
}
if (j == text.length) {
console.log(i - j); //this prints the starting index of the matching substring
}
}
};
These answers are all pretty good, but I'd probably opt for something like this:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = source.split(searchString);
var hitsCount = hits.length - 1;
This way you have all of the data you need to figure out where each hit occurred in he source, if that's important to you.

Code for Variations with repetition (combinatorics) using javascript?

Does anyone have Javascript code for generating all variations with repetition?
Example of variations with repetition:
(size=3, input=A,B)
AAA, AAB, ABA, BAA, ABB, BAB, BBA, BBB
What I need is to do something similar for numbers from 0-9 as the input and 6 digits length as size (according to my example).
Just to know, I got this working with a code in Java and also in .NET based on this project (check the link). All variations with repetition for what I need generates 1000000 values.
http://www.codeproject.com/KB/recipes/Combinatorics.aspx
Is it possible to do it in Javascript?
you have chosen the simplest case from combinatorics...
var i, n = 1000000;
for (i = 0; i < n; i++)
console.log(('' + (i + n)).substring(1));
will give you all the combinations of 0-9 in 6 spots (1000000 === Math.pow(10, 6)).
I've just wrote it right now, it needs more tests and optimizations but this should get you started:
​var input = "ABCD";
var size = 3;
var results = [];
function solve(i, elt) {
if(elt.length == size) {
results.push(elt);
return;
}
for(var j = 0; j < input.length; j++) {
solve(j, elt+input[j]);
}
}​​​​​​
solve(0, "");
​console​.log(results);​

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