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 :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.