Youāre certainly picking things up romeoanc
Just a bit of a look at your script and playing around with alternatives
var hits = 0
// instead of checking the length property each time
// we could assign it to a variable
// e.g. for (let i = 0, len = blacklist.length; i < len; i++)
for (var i = 0; i < blacklist.length; i++) {
var re = new RegExp('\\b' + blacklist[i] + '\\b', 'g')
// below we are doing the same match twice 'bio.match(re)'
// we could assign the match to a variable instead
// const match = bio.match(re)
// const quant = (match ? match.length : 0)
var quant = (bio.match(re) ? bio.match(re).length : 0)
if (quant !== 0) {
hits++
console.log(quant, 'EXACT Match/es for ' + blacklist[i])
continue // will jump to the next iteration of the loop
}
console.log('No Matches')
}
console.log('Total Found:', hits);
The above refactored into a forEach loop
// wrapped in an IIFE (immediately invoked function expression)
// this takes the code out of the global namespace
(function () {
const blacklist = [
'trans',
'apples',
'beer',
'beat',
'morning person',
'potato chips',
'instagram'
]
const bio = 'I translate texts, drink beer, beer and beer. I am not a morning person'
// not great having 'hits' be changed from inside the forEach function
// but for now....
let hits = 0
blacklist.forEach(function (word) {
const wordRx = new RegExp('\\b' + word + '\\b', 'g')
const matches = bio.match(wordRx) // will return an array or null if no matches
if (matches !== null) {
const matchCount = matches.length
console.log(matchCount + ' exact match/es for ' + word)
hits += matchCount
return // early return if a match (a bit like 'continue')
}
console.log('No match for ' + word)
})
console.log('Total Found', hits)
}());
Going for a more functional and declarative approach using filter and map and flat
(function () {
const blacklist = [
'trans',
'apples',
'beer',
'beat',
'morning person',
'potato chips',
'instagram'
]
const bio = 'I translate texts, drink beer, beer and beer. I am not a morning person'
function isMatch (needle, haystack) {
return new RegExp('\\b' + needle + '\\b', 'g').test(haystack)
}
function matches (needle, haystack) {
return haystack.match(new RegExp('\\b' + needle + '\\b', 'g'))
}
const hits = blacklist
.filter(function (word) { return isMatch(word, bio) })
.map(function (word) { return matches(word, bio) })
console.dir(hits)
// Array(2)
// 0: (3) ["beer", "beer", "beer"]
// 1: ["morning person"]
console.log('Total Found', hits.flat().length) // 4
}())
Iām moving on to currying here, to refactor further ā maybe a bit advanced. I would recommend looking into āclosuresā first
(function () {
const blacklist = [
'trans',
'apples',
'beer',
'beat',
'morning person',
'potato chips',
'instagram'
]
const bio = 'I translate texts, drink beer, beer and beer. I am not a morning person'
// this is currying.
const isMatch = haystack => needle => new RegExp('\\b' + needle + '\\b', 'g').test(haystack)
const matches = haystack => needle => haystack.match(new RegExp('\\b' + needle + '\\b', 'g'))
// a lot cleaner
const hits = blacklist
.filter(isMatch(bio)) // return matched words only
.map(matches(bio)) // return actual matches
console.dir(hits)
console.log('Total Found', hits.flat().length) // 4
}())
Finally we could go back to building our regex with the or(ā|ā) and all words
(function () {
const blacklist = [
'trans',
'apples',
'beer',
'beat',
'morning person',
'potato chips',
'instagram'
]
// \btrans\b|\bapples\b|\bbeer\b|\bbeat\b|\bmorning person\b|\bpotato chips\b|\binstagram\b
const blacklistRx = new RegExp('\\b' + blacklist.join('\\b|\\b') + '\\b', 'g')
const bio = 'I translate texts, drink beer, beer and beer. I am not a morning person'
// ['beer', 'beer', 'beer', 'morning person']
const hits = bio.match(blacklistRx)
console.log(hits) // (4) ["beer", "beer", "beer", "morning person"]
console.log('Total hits', hits.length) // 4
// sets only accept unique elements, so duplicates are ignored
// 'size' returns the number of elements, like length on an array
console.log('Total word matches', new Set(hits).size) // 2
}())
We could also use arrayās reduce method and a whole lot of alternatives, but hopefully there is something of use to you there.