0

I'm trying to loop through an array to check whether any of the words in the array are in a body of text:

for(var i = 0; i < wordArray.length; i++ ) {

if(textBody.indexOf(wordArray[i]) >= 1) {
    console.log("One or two words.");
    // do something
} 

else if (textBody.indexOf(wordArray[i]) >= 3) {
    console.log("Three or more words.");
    // do something
} 

else {
    console.log("No words match.");
    // do something
}
}
  • where >= 1 and >= 3 are supposed to determine the number of matched words (although it might just be determining their index position in the array? As, in its current state it will console.log hundreds of duplicate strings from the if / else statement).

How do I set the if / else statement to do actions based off of the amount of matched words?

Any help would be greatly appreciated!

Jack
  • 23
  • 1
  • 8

6 Answers6

1

Yes .indexOf gives you the first position of the word in the string. Many methods available to count a word in a string, I'm sharing my crazy version :

function matchesCount(word, str) {
    return (' ' + str.replace(/[^A-Za-z]+/gi,'  ') + ' ')
        .split(' '+word+' ').length - 1;
}
console.log(matchesCount('test', 'A test to test how many test in this'));
Bulent Vural
  • 2,630
  • 1
  • 13
  • 18
1

indexOf() provides the index of the first match, not the number of matches. So currently you're testing first if it appears at index one, then at index three - not counting the number of matches.

I can think of a couple different approaches off the top of my head that would work, but I'm not going to write them for you because this sounds like school work. One would be to use match: see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match and Count number of matches of a regex in Javascript

If you're scared of using regex, or can't be assed to spend the time learning how they work, you could get the index of the match, and if it matches make a substring excluding the portion up to that match, and test if it matches again, while incrementing a counter. indexOf() will return -1 if no matches are found.

Community
  • 1
  • 1
Our_Benefactors
  • 3,220
  • 3
  • 21
  • 27
1

You can split text to words with regExp and than find all occurrences of your word in this way

var text = "word1, word2, word word word word3"
var allWords = text.split(/\b/);
var getOccurrenceCount = function(word, allWords) {
 return allWords.reduce(function(count, nextWord) {
  count += word == nextWord ? 1 : 0;
  return count;
 }, 0);
};
getOccurrenceCount("word", allWords);
Artem Bozhko
  • 1,744
  • 11
  • 12
1

This may help you: You have to use .match instead of .indexOf (get the index of the first occurence inside the string)

var textBody = document.getElementById('inside').innerHTML;
var wordArray = ['check','test'];

for(var i = 0; i < wordArray.length; i++ ) {
  var regex = new RegExp( wordArray[i], 'g' );
  var wordCount = (textBody.match(regex) || []).length;
  console.log(wordCount + " times the word ["+ wordArray[i] +"]");
}
  
<body>
  <p id="inside">
  this is your test, check the test, how many test words check
  <p>
</body>
andrepaulo
  • 816
  • 11
  • 24
1

Try this:

for (var i = 0; i < wordArray.length; i++) {
    var regex = new RegExp('\\b' + wordArray[i] + '\\b', 'ig');
    var matches = textBody.match(regex);
    var numberOfMatches =  matches ? matches.length : 0;

    console.log(wordArray[i] + ' found ' + numberOfMatches + " times");
}

indefOf will do partial matches. For example "This is a bust".indexOf("bus") would match even though that is probably not what you want. It is better to use a regular expression with the word boundry token \b to eliminate partial word matches. In the Regexp constructor you need to escape the slash so \b becomes \\b. The regex uses the i flag to ignore case and the g flag to find all matches. Replace the console.log line with your if/else logic based on the numberOfMatches variable.

UPDATE: Per your clarification you would change the above to

var numberOfMatches = 0;
for (var i = 0; i < wordArray.length; i++) {
    var regex = new RegExp('\\b' + wordArray[i] + '\\b', 'ig');
    var matches = textBody.match(regex);
    numberOfMatches +=  matches ? matches.length : 0;
}
console.log(numberOfMatches);
ken_o
  • 374
  • 2
  • 8
  • That still seems to be giving a similar issue. Instead of `numberOfMatches` being one final value i.e. `3` which should ONLY trigger the `if` statement in: `if (numberOfMatches >=1) {console.log("1 or more")} {else { console.log("None"}`, it will instead run the if/else statement on each word and `console.log 'None'` for all that don't match, and `'1 or more'` for those that do. I was hoping there's a way to match numberOfMatches a single value that's finalized before I run the if/else statemnet. – Jack Feb 07 '17 at 19:48
  • Can you clarify something? Are you trying to find for each word in wordArray, how many times that word occurs in the textBody? Or are you trying to check how many of the words in the array occur at least one time in the textBody? – ken_o Feb 07 '17 at 19:57
  • Apologies if I wasn't clear. I'm trying to find the total amount of matches between the wordArray and textBody (including duplicates). So for example, if `textBody = "It's really amazing weather today. So amazing!"` and the `wordArray =["really", "amazing", "it's"]`, then it would return a single figure `numberOfMatches = 4` – Jack Feb 07 '17 at 20:03
  • I updated the answer to get the overall total of matches – ken_o Feb 07 '17 at 20:44
1

I would first put the array into a hashmap, something like _.each(array, function(a){map[a]=1})

Second split string into array by space and marks.

Loop through the new array to check if the word exist in the first map.

Make sure to compare string/words without cases.

This approach will help you improve the run time efficiency to linear.

user227353
  • 2,594
  • 2
  • 15
  • 13