以下是场景:仅在某些特定情况下减少元素。
EG。 val sen = List("Jone", "had", "a", "great", "time", ".")
,如果元素以“e”结尾,则将其与下一个元素连接起来。对于sen
,结果可能是("Jone had", "a", "great", "time .")
。
有没有优雅的方法来实现这些而不是循环?
答案 0 :(得分:4)
您可以简单地使用foldLeft
,如下所示:
val result = sen.foldLeft(List[String]()) {
(rs, s) =>
if (rs.nonEmpty && rs.head.endsWith("e"))
(rs.head + " " + s) :: rs.tail
else
s :: rs
}.reverse
只需用您自己的功能替换rs.head.endsWith("e")
。
答案 1 :(得分:2)
发布@kaktusito的foldLeft是最好的方法。以下是其工作方式的内部结构....大部分内容。
def partialReduce(list : List[String]): List[String] = {
@scala.annotation.tailrec
def internalRecurse(previousWord: String)(reducedList: List[String], finalList: List[String]): List[String] =
reducedList match {
case Nil => finalList :+ previousWord //No more words, just add the previous to the list and return
case head :: rest => {
//if ends with e, run through the rest with the new word being the old + the head
if(previousWord endsWith "e") internalRecurse(previousWord + " " + head)(rest, finalList)
//if doesn't end with e, append the previous word to the final list
//and run the rest with the head as the next to check
else internalRecurse(head)(rest, finalList :+ previousWord)
}
}
//Call the internal method only if there is at least one item in the list
list match {
case Nil => Nil
case head :: rest => internalRecurse(head)(rest, List())
}
}
此外,我将发布我的模式匹配版本,因为我更喜欢它的外观:
val result = sen.foldLeft(List[String]()) {
(curList, s) => {
curList match {
case Nil => List(s)
case head :: rest => {
if(head endsWith "e") head + " " + s :: rest
else s :: curList
}
}
}
}.reverse