2

I have an array:

var locations = ['Afghanistan','Albania','Algeria','New York']; 

and a string:

var string = 'I love Afghanistan New York Afghanistan Andorra Andorra Algeria New York'; 

I want to count the number of times each keyword in the array appears in the string but can't figure out the best way to do that.

4 Answers 4

5

Here is my version:

function countItems(a, s) { var x, i, output = {}; for (x = 0; x < a.length; x++) { i = 0; output[a[x]] = 0; while ((i = s.indexOf(a[x], i)) > -1) { output[a[x]]++; i++ } } return output; } var result = countItems(locations, string); // result['Albania'] === 0 

Try it out here.

Sign up to request clarification or add additional context in comments.

2 Comments

Suggestion: Do a reverse while-loop. That should speed things up a bit, when dealing with a large string and/or a large array.
this works great. The only thing I changed was that I hate how JS does associative arrays so instead I return a multi-dimensional array: output[keyword,count]
4

Try something like this. You could modify what you do with count -- store it in another array, display it (which is what this script does), etc.

var locations = ['Afghanistan','Albania','Algeria','New York']; var str = 'I love Afghanistan New York Afghanistan Andorra Andorra Algeria New York'; for(var i=0; i<locations.length; i++) { var pattern = new RegExp(locations[i], "g"); var m = str.match(pattern); if (m != null) { var count = m.length; // the count alert("There are " + count + " occurrences of " + locations[i]); } } 

Comments

1
<script language="JavaScript"> var locations = ['Afghanistan','Albania','Algeria','New York']; var string1 = 'I love Afghanistan New York Afghanistan Andorra Andorra Algeria New York'; for (var i=0;i<locations.length;i++) { nCount = string1.split(locations[i]).length-1; document.write(locations[i] + ' is found ' + nCount + ' times<br>'); } </script> 

1 Comment

Ingenious to use the pattern as a delimiter... A bit overkill, though, regarding you throw away the array.
1

This code only instantiates one RegExp object and uses a reverse while-loop. I'm pretty sure this is as fast as you can go without breaking the laws of physics :)

This is whats happening:

  1. Construct regular expression string using a reverse while-loop
  2. New up just one RegExp object, and match() it on the string
  3. Count the length of the array returned by the match() function

Here's the implementation:

var countries = ["Afganistan", "America", "Island"]; var sentence = "I love Afganistan, America.. And I love America some more"; function countOccurrences(a, s) { var re = "", l = a.length, m; while (l) { l--; re += a[l]; if (l > 0) re += "|"; } m = s.match(new RegExp(re, "gi")) || []; return m.length; } 

Note: I am of course expecting the entries in the array to be sanitized for any special characters that will break the regular expression constructed within the function.

var occurrences = function countOccurrences(countries, sentence); // returns 3 

2 Comments

this seems like a good solution but not to my problem. I want to know the count for EACH keyword. not for all together. thanks though!
Ah! Misunderstood your question. Thanks for the compliment though :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.