Folks, I've been writing some code in Scala lately to teach myself the language and in some recent experiments, I've used an NLP library to produce a set of part-of-speech tagged words from a user's input.
I want to write a function that gives me the first verb in the sentence. If there are no verbs, then I want to assume that the first word in the set is the verb (e.g. if the player just typed "who" or "uptime" , those are considered verbs by my game).
The following is a block of code so ugly only a mother could love, and it stinks of imperative programming and I want to refactor it into something more like idiomatic Scala, ideally something that doesn't have a single "if" statement in it.
def firstVerb = {
if (words.size == 1)
words.head.value
else {
val outWords = words.filter( word => word.pos == Verb)
if (outWords == Set.empty)
words.head.value
else
outWords.head.value
}
}
The "words" variable is of type ListBuffer[EnrichedWord], where EnrichedWord is my class that contains a part of speech (pos, contains case objects like Verb, Noun, etc) and the original word (value).
Any guidance you Scala geniuses can provide in refactoring this butt-ugly code would be fantastic.
This additionally handles the case when words
is empty, try it:
words.find(_.pos == Verb).orElse(words.headOption).map(_.value).getOrElse("")
If you are sure words
will never be an empty Set
, this one is simpler:
words.find(_.pos == Verb).getOrElse(words.head).value
BTW if you are using HashSet
the notion of some element being first doesn't really make sense. If each element represents a word in a sentece, it should have been a List
or a Seq
.
The canonical (point-free) version is probably:
words find(_.pos == Verb) orElse words.headOption map _.value getOrElse ""
Another option is:
(words.find(_.pos == Verb) ++ words.take(1)).take(1).map(_.value).mkString
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With