简体   繁体   中英

How to get total sum of matches from a loop?

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!

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'));

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.

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

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> 

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM