惯用斯卡拉列表理解 - 匹配的第一个项目

时间:2012-02-20 14:42:44

标签: java scala list-comprehension idiomatic

民间,   我最近在Scala中编写了一些代码来自学语言,在最近的一些实验中,我使用了用户输入中的an NLP library to produce a set of part-of-speech tagged words

我想写一个函数,它给出了句子中的第一个动词。如果没有动词,那么我想假设该组中的第一个单词是动词(例如,如果玩家只输入“who”或“uptime”,那些被我的游戏视为动词)。

以下是一段代码如此丑陋,只有母亲才会喜欢,而且命令式编程很糟糕,我想把它重构成更像是惯用的Scala,理想情况下没有单一的“if”语句在它。

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 
    }
}

“words”变量的类型为ListBuffer [EnrichedWord],其中EnrichedWord是我的类,它包含一个词性(pos,包含像Verb,Noun等案例对象)和原始词(值)。

Scala geniuses在重构这个对接丑陋的代码时可以提供的任何指导都很棒。

2 个答案:

答案 0 :(得分:9)

这另外处理words为空时的情况,尝试一下:

words.find(_.pos == Verb).orElse(words.headOption).map(_.value).getOrElse("")

如果您确定words永远不会是空的Set,那么这个更简单:

words.find(_.pos == Verb).getOrElse(words.head).value

顺便说一句,如果你使用的是HashSet,那么某些元素首先出现的概念并没有多大意义。如果每个元素代表一个单词,那么它应该是ListSeq

答案 1 :(得分:2)

规范(无点)版本可能是:

words find(_.pos == Verb) orElse words.headOption map _.value getOrElse ""

另一种选择是:

(words.find(_.pos == Verb) ++ words.take(1)).take(1).map(_.value).mkString