Reputation: 185
I'd like to check if there is any spam words in user submitted text. So here is the function that I've written:
func TextHasSpamWords(text string, spamWords []string) bool {
removePunctuation := func(r rune) rune {
if strings.ContainsRune(".,:;", r) {
return -1
} else {
return r
}
}
text = strings.Map(removePunctuation, text)
sort.Strings(spamWords)
for _, word := range text {
for _, sapmWord := range spamWords {
if word == sapmWord {
return true
}
}
}
}
But I get mismatched type rune and string
at word == sapmWord
.
I know this is because removePunctuation
returns runes (aka int32) which can not be compared with string (unit8). But removing punctiuations is indispensible for the function to work so I'm wondering how can I fix this? Or perhaps there is a more idiomatic way to do so?
Upvotes: 1
Views: 3542
Reputation: 34307
Consider using a map for the lookup
lookupSpam := make(map[string]bool)
for _, v := range spamWords {
lookupSpam[v] = true
}
Then instead of
for _, word := range textArr {
for _, sapmWord := range spamWords {
if word == sapmWord {
return true
}
}
}
something like this can be used
for _, word := range textArr {
_,found:=lookupSpam[word]
if found {
return true
}
}
If you are repeatedly checking the same set of words then set up the map once and reuse it
Upvotes: 3
Reputation: 2719
You are trying to compare a letter vs a string.
When you are doing for _, word := range text
, it's not word, it's letter
. If you want the words, you have to split the string in a slice of words with textArr := strings.Split(text, " ")
(split by whitespace)
func TextHasSpamWords(text string, spamWords []string) bool {
removePunctuation := func(r rune) rune {
if strings.ContainsRune(".,:;", r) {
return -1
} else {
return r
}
}
text = strings.Map(removePunctuation, text)
textArr := strings.Split(text, ` `)
sort.Strings(spamWords)
for _, word := range textArr {
for _, sapmWord := range spamWords {
if word == sapmWord {
return true
}
}
}
return false
}
Upvotes: 3