【问题标题】:Can map/flatMap sequence with several paths be translated a for-comprehension?可以将具有多个路径的 map/flatMap 序列翻译为易于理解吗?
【发布时间】:2015-07-01 13:54:58
【问题描述】:

我认为这是不可能的,但也许我错过了什么?

这是一个例子

val sentences = "hello.what is your name?I am Loïc"     

sentences.split("\\.|\\?").flatMap { sentence =>
  if (sentence.startsWith("h")) sentence.split(" ").map(word => word.toUpperCase)
  else if (sentence.startsWith("w")) sentence.split(" ").flatMap(word => List(word.toUpperCase, "-").map(word => word.toUpperCase))
  else List(sentence)
}

这可以翻译成一个易于理解的表达式吗?

我注意到,如果我需要在服务响应上进行模式匹配,那么当我在期货上使用 map/flatMap 时(例如在 web 服务调用上),我经常会遇到这种模式。所以我正在努力提高可读性。

谢谢:)

【问题讨论】:

  • 你所说的“理解表达”是什么意思?您想将 flatMap 转换为 foreach 循环吗??
  • @eliasah 我的意思是 for { book book.author startsWith " bob").map(book => book.title)

标签: scala


【解决方案1】:

您可以将外部构造转换为 for/yield,并将 if/else 的分支转换为它们自己的 for/yield:

for {
  sentence ← sentences.split("\\.|\\?")
  out ← if (sentence.startsWith("h"))
      for {word ← sentence.split(" ")} yield word.toUpperCase
    else if (sentence.startsWith("w"))
      for {word ← sentence.split(" ")
           w ← List(word.toUpperCase, "-") } yield w.toUpperCase
    else List(sentence)
} yield out

如果您可以从分支中提取一些共性,您也许可以将它们组合成一个高阶函数调用,而不是 if/else,例如通过使用 scalaz 的traverse,或者通过将sentence 设置为具有子类的对象来使用多态性,这样分支就变成了一个方法调用。但一般来说,如果分支之间没有任何共同点,那么您将不得不单独处理它们(这是有道理的,不是吗?)。

【讨论】:

    猜你喜欢
    • 2014-08-16
    • 2014-12-14
    • 2013-11-29
    • 2019-07-05
    • 1970-01-01
    • 2014-06-11
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多