2012-02-20 50 views
7

Folks, 我最近在Scala上编写了一些代码来教我自己的语言,在最近的一些实验中,我从用户的输入中使用了an NLP library to produce a set of part-of-speech tagged wordsIdiomatic Sc​​ala List Comprehension - 第一个匹配的项目

我想写一个函数,给我第一个动词的句子。如果没有动词,那么我想假定集合中的第一个单词是动词(例如,如果玩家只是输入“谁”或“正常运行时间”,那么这些被我的游戏视为动词)。

以下是一段如此丑陋的代码块,只有母亲才会喜欢,而且它对命令式编程很臭,我想将它重构成更像惯用的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 
    } 
} 

的“字”变量的类型ListBuffer [EnrichedWord],其中EnrichedWord是我的类,它包含语音的部分的(位置,包含壳体对象像动词,名词,等)和原始单词(值)。

任何指导你斯卡拉天才可以提供重构这个对接丑陋的代码将是太棒了。

+0

“......只有妈妈才会喜欢。” “ – 2017-06-16 10:10:04

+0

......只有一位母亲才会喜欢。”我今天看过的最佳短语! – 2017-06-16 10:11:55

回答

9

这额外处理的情况下words是空的,试试吧:

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

如果你确信words绝不会是一个空Set,这个人是简单的:

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

顺便说一句,如果你正在使用HashSet某些元素的第一个概念没有意义。如果每个元素代表一个Sentece中的单词,则它应该是ListSeq

+0

尝试了对ListBuffer的第一个选项(你说得对,Set在这里没有意义)并且得到了:error:value map不是成员ScalaObject with java.io.Serializable \t \t words.find(_。pos == Verb).getOrElse(words.headOption).map(_。value) – 2012-02-20 15:04:28

+4

@KevinHoffman然后用'orElse'替换'getOrElse'。 – 2012-02-20 15:21:42

+0

@Jean -PhilippePellet:确实,谢谢!我更新了我的答案 – 2012-02-20 15:25:14

2

的规范(自由点)版本可能是:

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

另一种选择是:

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

单词可以是空的 - 例如玩家可以击中输入并提交空白命令 – 2012-02-20 15:16:46

+0

@KevinHoffman - 该代码应该做什么? – 2012-02-20 15:18:11

+0

如果单词为空,我现在只是第一个动词返回“”。我不喜欢传递空值,也不喜欢让下游代码做一些/不检查。 – 2012-02-20 15:30:33

相关问题