Finding the nth occurrence of a character in a string in javascript - javascript

I am working on a javascript code to find the nth occurrence of a character in a string. Using the indexOf() function we are able to get the first occurrence of the character. Now the challenge is to get the nth occurrence of the character. I was able to get the second third occurrence and so on using the code given below:
function myFunction() {
var str = "abcdefabcddesadfasddsfsd.";
var n = str.indexOf("d");
document.write("First occurence " +n );
var n1 = str.indexOf("d",parseInt(n+1));
document.write("Second occurence " +n1 );
var n2 = str.indexOf("d",parseInt(n1+1));
document.write("Third occurence " +n2 );
var n3 = str.indexOf("d",parseInt(n2+1));
document.write("Fourth occurence " +n3);
// and so on ...
}
The result is given below
First occurence 3
Second occurence 9
Third occurence 10
Fourth occurence 14
Fifth occurence 18
Sixth occurence 19
I would like to generalize the script so that I am able to find the nth occurrence of the character as the above code requires us to repeat the script n times. Let me know if there is a better method or alternative to do the same. It would be nice if we just give the occurrence (at run time) to get the index of that character.
The following are some of my questions:
How do we do it in JavaScript?
Does any framework provide any functionality to do the same implementation in an easier way or what are the alternate methods to implement the same in other frameworks /languages?

function nth_occurrence (string, char, nth) {
var first_index = string.indexOf(char);
var length_up_to_first_index = first_index + 1;
if (nth == 1) {
return first_index;
} else {
var string_after_first_occurrence = string.slice(length_up_to_first_index);
var next_occurrence = nth_occurrence(string_after_first_occurrence, char, nth - 1);
if (next_occurrence === -1) {
return -1;
} else {
return length_up_to_first_index + next_occurrence;
}
}
}
// Returns 16. The index of the third 'c' character.
nth_occurrence('aaaaacabkhjecdddchjke', 'c', 3);
// Returns -1. There is no third 'c' character.
nth_occurrence('aaaaacabkhjecdddhjke', 'c', 3);

You can do it easily by implementing a function using charAt(), like this:
function nth_ocurrence(str, needle, nth) {
for (i=0;i<str.length;i++) {
if (str.charAt(i) == needle) {
if (!--nth) {
return i;
}
}
}
return false;
}
alert( nth_ocurrence('aaaaacabkhjecdddchjke', 'c', 3) );//alerts 16
Thanks to CQQL for let me know what OP really wanted. I updated a bit my original function to achieve the new behaviour.

indexOf takes a second argument, the character index in the string to begin the search.
function nthChar(string, character, n){
var count= 0, i=0;
while(count<n && (i=string.indexOf(character,i)+1)){
count++;
}
if(count== n) return i-1;
return NaN;
}
var s= 'abcbbasdbgasdnnaabaasdert';
nthChar(s,'a',7);

So a nice way to do this is to extend the string class like so:
(function() {
String.prototype.nthOccurrenceIndex = function(charToMatch, occurrenceIndex) {
var char, index, matches, _i, _len;
matches = 0;
index = 0;
for (_i = 0, _len = this.length; _i < _len; _i++) {
char = this[_i];
if (char === charToMatch) {
matches += 1;
if (matches === occurrenceIndex) {
return index;
}
}
index += 1;
}
return -1;
};
}).call(this);
The much more concise CoffeeScript version:
String.prototype.nthOccurrenceIndex = (charToMatch, occurrenceIndex)->
matches = 0
index = 0
for char in #
if char is charToMatch
matches += 1
return index if matches is occurrenceIndex
index += 1
-1
So now you can do stuff like:
"abcabc".nthOccurrenceIndex('a', 1)
# -> 0
"abcabc".nthOccurrenceIndex('a', 2)
# -> 3
"abcabc".nthOccurrenceIndex('a', 3)
# -> -1

A maybe clearer function. Recursive and copy the mechanism of indexOf:
Doesn't cause an error if an incorrect number for nth (ie <= 0). It will return -1 like you can give a negative number (or greater than the length of the string) asfromIndex to indexOf.
Can take a fromIndex argument (the same than for indexOf: An integer representing the index at which to start the search; the default value is 0.)
function indexOfNth (string, char, nth, fromIndex=0) {
let indexChar = string.indexOf(char, fromIndex);
if (indexChar === -1){
return -1;
} else if (nth === 1) {
return indexChar;
} else {
return indexOfNth(string, char, nth-1, indexChar+1);
}
}
let test = 'string for research purpose';
console.log('first s:', indexOfNth(test, 's', 1));
console.log('second s:', indexOfNth(test, 's', 2));
console.log('15th s:', indexOfNth(test, 's', 15));
console.log('first z:', indexOfNth(test, 'z', 1));
console.log('-1th s:', indexOfNth(test, 's', -1));
console.log('first s starting from index=1:', indexOfNth(test, 's', 1, 1));

function nthIndexOf(search, n) {
var myArray = [];
for(var i = 0; i < myStr.length; i++) {
if(myStr.slice(i, i + search.length) === search) {
myArray.push(i);
}
}
return myArray[n - 1];
}

Related

Remove invalid parenthesis - JS (Leetcode301)

I've been taking leetcode challenges and come across this interesting problem: 301. Remove Invalid Parentheses:
Given a string s that contains parentheses and letters, remove the minimum number of invalid parentheses to make the input string valid.
Return all the possible results. You may return the answer in any order.
Example 1:
Input: s = "()())()"
Output: ["(())()","()()()"]
Example 2:
Input: s = "(a)())()"
Output: ["(a())()","(a)()()"]
Example 3:
Input: s = ")("
Output: [""]
Constraints:
1 <= s.length <= 25
s consists of lowercase English letters and parentheses '(' and ')'.
There will be at most 20 parentheses in s.
I tried to solve it using recursion, but something is not right about my code, it's returning an empty array instead of the results.
Here is the code:
var removeInvalidParentheses = function(s) {
const validExpressions = [];
let minimumRemoved = 0;
function recurse(s, index, leftCount, rightCount, expression, removedCount) {
let possibleAnswer;
if (index === s.length) {
if (leftCount === rightCount) {
if (removedCount <= minimumRemoved) {
possibleAnswer = expression.join("");
if (removedCount < minimumRemoved) {
validExpressions.length = 0;
minimumRemoved = removedCount;
}
validExpressions.push(possibleAnswer);
}
}
} else {
let currentCharacter = s[index];
let length = expression.length;
if (currentCharacter !== '(' && currentCharacter !== ')') {
expression.push(currentCharacter);
recurse(s, index + 1, leftCount, rightCount, expression, removedCount);
expression.splice(length, 1);
} else {
recurse(s, index + 1, leftCount, rightCount, expression, removedCount + 1);
expression.push(currentCharacter);
if (currentCharacter == '(') {
recurse(s, index + 1, leftCount + 1, rightCount, expression, removedCount);
} else if (rightCount < leftCount) {
recurse(s, index + 1, leftCount, rightCount + 1, expression, removedCount);
}
expression.splice(length, 1);
}
}
}
recurse(s, 0, 0, 0, [], 0);
return validExpressions;
}
The problem is that you initialise minimumRemoved = 0 which makes it impossible to ever satisfy the condition if (removedCount <= minimumRemoved) { except if removeCount is 0. But if there is no match in that condition, nothing will be ever pushed to validExpressions.
You'll want to mimic the worst situation possible, so that any solution will be considered to be better than that. Therefore initialise removedCount as a high number, like s.length + 1 or -- why not -- Infinity.
There is a second issue in your code: it may collect duplicate values in validExpressions, so make your return statement like this:
return [...new Set(validExpressions)];
This will make it work. Now, this is not a very fast solution. You may want to try to find improvements.
The problems are correctly highlihted by trincot. Here is the final code:
let removeInvalidParentheses = function (s) {
const validExpressions = [];
let minimumRemoved = Number.MAX_SAFE_INTEGER;
function recurse(
s,
index,
leftCount,
rightCount,
expression,
removedCount
) {
let possibleAnswer;
// If we have reached the end of string.
if (index === s.length) {
// If the current expression is valid.
if (leftCount === rightCount) {
// If the current count of removed parentheses is <= the current minimum count
if (removedCount <= minimumRemoved) {
// Convert StringBuilder to a String. This is an expensive operation.
// So we only perform this when needed.
possibleAnswer = expression.join("");
// If the current count beats the overall minimum we have till now
if (removedCount < minimumRemoved) {
validExpressions.length = 0;
minimumRemoved = removedCount;
}
validExpressions.push(possibleAnswer);
}
}
} else {
let currentCharacter = s[index];
let length = expression.length;
// If the current character is neither an opening bracket nor a closing one,
// simply recurse further by adding it to the expression StringBuilder
if (currentCharacter !== "(" && currentCharacter !== ")") {
expression.push(currentCharacter);
recurse(
s,
index + 1,
leftCount,
rightCount,
expression,
removedCount
);
expression.splice(length, 1);
} else {
// Recursion where we delete the current character and move forward
recurse(
s,
index + 1,
leftCount,
rightCount,
expression,
removedCount + 1
);
expression.push(currentCharacter);
// If it's an opening parenthesis, consider it and recurse
if (currentCharacter == "(") {
recurse(
s,
index + 1,
leftCount + 1,
rightCount,
expression,
removedCount
);
} else if (rightCount < leftCount) {
// For a closing parenthesis, only recurse if right < left
recurse(
s,
index + 1,
leftCount,
rightCount + 1,
expression,
removedCount
);
}
// Undoing the append operation for other recursions.
expression.splice(length, 1);
}
}
}
recurse(s, 0, 0, 0, [], 0);
return Array.from(new Set(validExpressions));
};

Check how many times a char appears in a string

Simply trying to find how many times a given character appears in a string but I can't solve it any other way then this simple for-loop. Is there a method that would solve this quicker or more eloquently other than using Regex?
function countCharacter(str, char) {
var count = 0;
for(var i = 0; i < str.length; i++){
if(str.charAt(i) === char)
count++;
}
return count;
}
There are many possible ways are available in the market.
I am adding a few of them.
Method 1:
str = "The man is as good as his word"
str.split('a')
output: (4) ["The m", "n is ", "s good ", "s his word"]
str.split('a').length - 1
output: 3
Method 2:
str = "The man is as good as his word"
str.split('').map( function(char,i)
{ if(char === 'a')
return i;
}
).filter(Boolean)
Output: (3) [5, 11, 19]
str.split('').map( function(char,i)
{ if(char === 'a')
return i;
}
).filter(Boolean).length
ouput: 3
Edit: As per comment we can also make use of filter().
str.split('').filter(function(char, i){
if(char == 'a'){
return i;
}
})
output: (3) ["a", "a", "a"]
str.split('').filter(function(char, i){
if(char == 'a'){
return i;
}
}).length
output: 3
----edited by adding more cases from answers----
there are several ways, you can use split/for/regex/reduce/indexOf like this:
function countCharacter_reduce(str, ch) {
return Array.prototype.reduce.call(str, (prev, cur) => cur === ch && ++prev && prev, 0);
}
function countCharacter_split(str, ch) {
return str.split(ch).length - 1;
}
function countCharacter_for(str, ch) {
for (var count = 0, ii = 0; ii < str.length; ii++) {
if (str[ii] === ch)
count++;
}
return count;
}
function countCharacter_regex(str, ch) {
return str.length - str.replace(new RegExp(ch, 'g'), '').length;
}
function countCharacter_indexOf(str, char) {
var start = 0;
var count = 0;
while ((start = str.indexOf(char, start) + 1) !== 0) {
count++;
}
return count;
}
performance of them by running 1,000,000 times on counting '/' in a string.
-- case1: running 1000000 times on ( 'this/is/a/path/with/extension', '/' )
countCharacter_reduce: 2389.880ms
countCharacter_regex: 496.251ms
countCharacter_split: 114.709ms
countCharacter_for: 152.012ms
countCharacter_indexOf: 90.330ms
-- case2: running 1000000 times on ( '////////////', '/' )
countCharacter_reduce: 1138.051ms
countCharacter_regex: 619.886ms
countCharacter_split: 121.945ms
countCharacter_for: 74.542ms
countCharacter_indexOf: 204.242ms
Conclusion ('>' means 'has better performance'):
for|split|indexOf > regex > reduce.
furthermore,
if the string contains more searching characters (like case2),
for>split>indexOf,
otherwise (like case1)
indexOf > split > for.
BTW: you can change the for indexOf method to fit multi-characters search (example is single character)
using reduce:
function countCharacter(str, char) {
return str.split('').reduce((a, x) => x === char ? ++a : a, 0);
}
I guess this involves regex which you wanted to avoid but it's pretty quick:
function countCharacter(str, char) {
return str.length - str.replace(new RegExp(char,"g"),"").length;
}
You can also try the str.split(char).length-1 approach suggested by Jaromanda.
Or, go all out with some fun recursion (pass 0 to startingFrom):
function countCharacter(str, char, startingFrom) {
var idx = str.indexOf(char, startingFrom);
return idx == -1 ? 0 : 1 + countCharacter(str, char, idx + 1);
}
You can get rid of the annoying extra argument at the cost of some efficiency:
function countCharacter(str, char) {
var idx = str.indexOf(char);
return idx == -1 ? 0 : 1 + countCharacter(str.substr(idx+1), char);
}
And here's a version optimized for speed (this is about 3 times faster on my browser than your original and much faster than the regex versions, according to jsperf):
function countCharacter(str, char) {
var start = 0;
var count = 0;
while((start = str.indexOf(char, start)+1) !== 0) {
count++;
}
return count;
}
Note that the indexOf approaches will generally be substantially faster than manually iterating through the string. See jsperf
Here you go. One line code
"hello".match(new RegExp('l','g')).length
replace 'l' with any char here, new RegExp('l','g').
that is
str.match(new RegExp(char,'g')).length
Have you thought of using the split() method? How about this -
function myFunction(str, char) {
return string.split(char).length - 1
}
Let me know what you think of this solution.

Inserting into a number string

Have the function DashInsert(num) insert dashes ('-') between each two odd numbers in num. For example: if num is 454793 the output should be 4547-9-3. Don't count zero as an odd number.
Here is my code (not working). When I run it, I get the same response as an infinite loop where I have to kill the page but I can't see why. I know there are ways to do this by keeping it as a string but now I'm wondering why my way isn't working. Thanks...
function DashInsert(num) {
num = num.split("");
for (i = 1; i < num.length; i++) {
if (num[i - 1] % 2 != 0 && num[i] % 2 != 0) {
num.splice(i, 0, "-");
}
}
num = num.join("");
return num;
}
Using num.splice you are inserting new entries into the array, therefor increasing its length – and that makes the value of i “running behind” the increasing length of the array, so the break condition is never met.
And apart from that, on the next iteration after inserting a -, num[i-1] will be that - character, and therefor you are practically trying to check if '-' % 2 != 0 … that makes little sense as well.
So, when you insert a - into the array, you have to increase i by one as well – that will a) account for the length of the array having increased by one, and also it will check the next digit after the - on the next iteration:
function DashInsert(num) {
num = num.split("");
for (i = 1; i < num.length; i++) {
if (num[i - 1] % 2 != 0 && num[i] % 2 != 0) {
num.splice(i, 0, "-");
i++; // <- this is the IMPORTANT part!
}
}
num = num.join("");
return num;
}
alert(DashInsert("454793"));
http://jsfiddle.net/37wA9/
Once you insert a dash -, the if statement is checking this '-'%2 != 0 which is always true and thus inserts another dash, ad infinitum.
Here's one way to do it with replace using a regex and function:
function DashInsert(n) {
var f = function(m,i,s) { return m&s[i+1]&1 ? m+'-' : m; };
return String(n).replace(/\d/g,f);
}
DashInsert(454793) // "4547-9-3"
When you are adding a dash, this dash will be processed as a number on the next iteration. You need to forward one step.
function DashInsert(num) {
var num = num.split("");
for (var i = 1; i < num.length; i++) {
if ((num[i - 1] % 2 != 0) && (num[i] % 2 != 0)) {
num.splice(i, 0, "-");
i++; // This is the only thing that needs changing
}
}
num = num.join("");
return num;
}
It's because there are cases when you use the % operator on dash '-' itself, e.g. right after you splice a dash into the array.
You can correct this behavior by using a clone array.
function DashInsert(num) {
num = num.split("");
var clone = num.slice(0);
var offset = 0;
for (i = 1; i < num.length; i++) {
if (num[i - 1] % 2 != 0 && num[i] % 2 != 0) {
clone.splice(i + offset, 0, "-");
offset++;
}
}
return clone.join("");
}
alert(DashInsert("45739"));
Output: 45-7-3-9
Demo: http://jsfiddle.net/262Bf/
To complement the great answers already given, I would like to share an alternative implementation, that doesn't modify arrays in-place:
function DashInsert(num) {
var characters = num.split("");
var numbers = characters.map(function(chr) {
return parseInt(chr, 10);
});
var withDashes = numbers.reduce(function(result, current) {
var lastNumber = result[result.length - 1];
if(lastNumber == null || current % 2 === 0 || lastNumber % 2 === 0) {
return result.concat(current);
} else {
return result.concat("-", current);
}
}, []);
return withDashes.join("");
}
It's longer, but IMHO reveals the intention better, and avoids the original issue.

How to sort strings in JavaScript numerically

I would like to sort an array of strings (in JavaScript) such that groups of digits within the strings are compared as integers not strings. I am not worried about signed or floating point numbers.
For example, the result should be ["a1b3","a9b2","a10b2","a10b11"] not ["a1b3","a10b11","a10b2","a9b2"]
The easiest way to do this seems to be splitting each string on boundaries around groups of digits. Is there a pattern I can pass to String.split to split on character boundaries without removing any characters?
"abc11def22ghi".split(/?/) = ["abc","11","def","22","ghi"];
Or is there another way to compare strings that does not involve splitting them up, perhaps by padding all groups of digits with leading zeros so they are the same length?
"aa1bb" => "aa00000001bb", "aa10bb" => "aa00000010bb"
I am working with arbitrary strings, not strings that have a specific arrangement of digit groups.
I like the /(\d+)/ one liner from Gaby to split the array. How backwards compatible is that?
The solutions that parse the strings once in a way that can be used to rebuild the originals are much more efficient that this compare function. None of the answers handle some strings starting with digits and others not, but that would be easy enough to remedy and was not explicit in the original question.
["a100", "a20", "a3", "a3b", "a3b100", "a3b20", "a3b3", "!!", "~~", "9", "10", "9.5"].sort(function (inA, inB) {
var result = 0;
var a, b, pattern = /(\d+)/;
var as = inA.split(pattern);
var bs = inB.split(pattern);
var index, count = as.length;
if (('' === as[0]) === ('' === bs[0])) {
if (count > bs.length)
count = bs.length;
for (index = 0; index < count && 0 === result; ++index) {
a = as[index]; b = bs[index];
if (index & 1) {
result = a - b;
} else {
result = !(a < b) ? (a > b) ? 1 : 0 : -1;
}
}
if (0 === result)
result = as.length - bs.length;
} else {
result = !(inA < inB) ? (inA > inB) ? 1 : 0 : -1;
}
return result;
}).toString();
Result: "!!,9,9.5,10,a3,a3b,a3b3,a3b20,a3b100,a20,a100,~~"
Another variant is to use an instance of Intl.Collator with the numeric option:
var array = ["a100", "a20", "a3", "a3b", "a3b100", "a3b20", "a3b3", "!!", "~~", "9", "10", "9.5"];
var collator = new Intl.Collator([], {numeric: true});
array.sort((a, b) => collator.compare(a, b));
console.log(array);
I think this does what you want
function sortArray(arr) {
var tempArr = [], n;
for (var i in arr) {
tempArr[i] = arr[i].match(/([^0-9]+)|([0-9]+)/g);
for (var j in tempArr[i]) {
if( ! isNaN(n = parseInt(tempArr[i][j])) ){
tempArr[i][j] = n;
}
}
}
tempArr.sort(function (x, y) {
for (var i in x) {
if (y.length < i || x[i] < y[i]) {
return -1; // x is longer
}
if (x[i] > y[i]) {
return 1;
}
}
return 0;
});
for (var i in tempArr) {
arr[i] = tempArr[i].join('');
}
return arr;
}
alert(
sortArray(["a1b3", "a10b11", "a10b2", "a9b2"]).join(",")
);
Assuming you want to just do a numeric sort by the digits in each array entry (ignoring the non-digits), you can use this:
function sortByDigits(array) {
var re = /\D/g;
array.sort(function(a, b) {
return(parseInt(a.replace(re, ""), 10) - parseInt(b.replace(re, ""), 10));
});
return(array);
}
It uses a custom sort function that removes the digits and converts to a number each time it's asked to do a comparison. You can see it work here: http://jsfiddle.net/jfriend00/t87m2/.
Use this compare function for sorting...
function compareLists(a, b) {
var alist = a.split(/(\d+)/), // Split text on change from anything
// to digit and digit to anything
blist = b.split(/(\d+)/); // Split text on change from anything
// to digit and digit to anything
alist.slice(-1) == '' ? alist.pop() : null; // Remove the last element if empty
blist.slice(-1) == '' ? blist.pop() : null; // Remove the last element if empty
for (var i = 0, len = alist.length; i < len; i++) {
if (alist[i] != blist[i]){ // Find the first non-equal part
if (alist[i].match(/\d/)) // If numeric
{
return +alist[i] - +blist[i]; // Compare as number
} else {
return alist[i].localeCompare(blist[i]); // Compare as string
}
}
}
return true;
}
Syntax
var data = ["a1b3", "a10b11", "b10b2", "a9b2", "a1b20", "a1c4"];
data.sort(compareLists);
alert(data);
There is a demo at http://jsfiddle.net/h9Rqr/7/.
Here's a more complete solution that sorts according to both letters and numbers in the strings
function sort(list) {
var i, l, mi, ml, x;
// copy the original array
list = list.slice(0);
// split the strings, converting numeric (integer) parts to integers
// and leaving letters as strings
for( i = 0, l = list.length; i < l; i++ ) {
list[i] = list[i].match(/(\d+|[a-z]+)/g);
for( mi = 0, ml = list[i].length; mi < ml ; mi++ ) {
x = parseInt(list[i][mi], 10);
list[i][mi] = !!x || x === 0 ? x : list[i][mi];
}
}
// sort deeply, without comparing integers as strings
list = list.sort(function(a, b) {
var i = 0, l = a.length, res = 0;
while( res === 0 && i < l) {
if( a[i] !== b[i] ) {
res = a[i] < b[i] ? -1 : 1;
break;
}
// If you want to ignore the letters, and only sort by numbers
// use this instead:
//
// if( typeof a[i] === "number" && a[i] !== b[i] ) {
// res = a[i] < b[i] ? -1 : 1;
// break;
// }
i++;
}
return res;
});
// glue it together again
for( i = 0, l = list.length; i < l; i++ ) {
list[i] = list[i].join("");
}
return list;
}
I needed a way to take a mixed string and create a string that could be sorted elsewhere, so that numbers sorted numerically and letters alphabetically. Based on answers above I created the following, which pads out all numbers in a way I can understand, wherever they appear in the string.
function padAllNumbers(strIn) {
// Used to create mixed strings that sort numerically as well as non-numerically
var patternDigits = /(\d+)/g; // This recognises digit/non-digit boundaries
var astrIn = strIn.split( patternDigits ); // we create an array of alternating digit/non-digit groups
var result = "";
for (var i=0;i<astrIn.length; i++) {
if (astrIn[i] != "") { // first and last elements can be "" and we don't want these padded out
if (isNaN(astrIn[i])) {
result += astrIn[i];
} else {
result += padOneNumberString("000000000",astrIn[i]);
}
}
}
return result;
}
function padOneNumberString(pad,strNum,left) {
// Pad out a string at left (or right)
if (typeof strNum === "undefined") return pad;
if (typeof left === "undefined") left = true;
var padLen = pad.length - (""+ strNum).length;
var padding = pad.substr(0,padLen);
return left? padding + strNum : strNum + padding;
}
Sorting occurs from left to right unless you create a custom algorithm. Letters or digits are compared digits first and then letters.
However, what you want to accomplish as per your own example (a1, a9, a10) won’t ever happen. That would require you knowing the data beforehand and splitting the string in every possible way before applying the sorting.
One final alternative would be:
a) break each and every string from left to right whenever there is a change from letter to digit and vice versa; &
b) then start the sorting on those groups from right-to-left. That will be a very demanding algorithm. Can be done!
Finally, if you are the generator of the original "text", you should consider NORMALIZING the output where a1 a9 a10 could be outputted as a01 a09 a10. This way you could have full control of the final version of the algorithm.

Counting the number of times a pattern appears in a string

What is the best method for counting the number of times a string appears within a string using JS?
For example:
count("fat math cat", "at") returns 3
Use a regex and then the number of matches can be found from the returned array. This is the naive approach using regex.
'fat cat'.match(/at/g).length
To protect against cases where the string doesn't match, use:
( 'fat cat'.match(/at/g) || [] ).length
Here:
function count( string, substring ) {
var result = string.match( RegExp( '(' + substring + ')', 'g' ) );
return result ? result.length : 0;
}
Don't use this, it's overcomplicated:
function count(sample, searchTerm) {
if(sample == null || searchTerm == null) {
return 0;
}
if(sample.indexOf(searchTerm) == -1) {
return 0;
}
return count(sample.substring(sample.indexOf(searchTerm)+searchTerm.length), searchTerm)+1;
}
Can use indexOf in a loop:
function count(haystack, needle) {
var count = 0;
var idx = -1;
haystack.indexOf(needle, idx + 1);
while (idx != -1) {
count++;
idx = haystack.indexOf(needle, idx + 1);
}
return count;
}
function count(str,ma){
var a = new RegExp(ma,'g'); // Create a RegExp that searches for the text ma globally
return str.match(a).length; //Return the length of the array of matches
}
Then call it the way you did in your example. count('fat math cat','at');
You can use split also:
function getCount(str,d) {
return str.split(d).length - 1;
}
getCount("fat math cat", "at"); // return 3

Categories