Smn
Smn

Reputation: 185

How to check if a text contains any of the words in a list in Golang?

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

Answers (2)

Vorsprung
Vorsprung

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

TBouder
TBouder

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

Related Questions