在相同的代码块上减少和折叠的奇怪行为

时间:2012-04-08 18:24:03

标签: scala conditional ternary

修改
好的,@ dhg发现如果fold()的代码块没有绑定到val(为什么在同一个代码块中使用reduce(),可以使用空格方法语法,我不知道是否需要点方法语法) 。无论如何,最终的结果是非常简洁:

result.map { row =>
  addLink( row.href, row.label )
}.fold(NodeSeq.Empty)(_++_)

在某种程度上否定了原始问题;即,在许多情况下,一个人可以更高阶地离开任何一个/或场景,并避免“胖”,重复的if / else陈述。

ORIGINAL
在使用List [T]

等可能为空的集合时,尝试减少if / else处理

例如,假设我需要获取最新新闻文章,以构建html新闻<li><a>links</a></li> NodeSeq

val result = dao.getHeadlines // List[of model objects]
if(result.isEmpty) NodeSeq.Empty
else 
  result map { row =>
    addLink( row.href, row.label ) // NodeSeq
  } reduce(_ ++ _)

这很好,非常简洁,但我发现自己想要采用三元风格来解决这些问题,而这些风格只会是/或者是:

result.isEmpty ? NodeSeq.Empty :
  result map { row =>
    addLink( row.href, row.label )
  } reduce(_ ++ _)

我已经看到一些关于将三元组拉到布尔上的旧帖子,但很想知道替代方案是什么,如果有的话,简化if / else?

IMO对于这种情况来说,{p> match {...}有点臃肿,而for {...} yield似乎也没什么帮助。

1 个答案:

答案 0 :(得分:3)

你根本不需要检查空虚。只需使用fold代替reduce,因为fold允许您指定默认的“空”值:

scala> List(1,2,3,4).map(_ + 1).fold(0)(_+_)
res0: Int = 14

scala> List[Int]().map(_ + 1).fold(0)(_+_)
res1: Int = 0

以下是List Seq s的示例:

scala> List(1,2).map(Seq(_)).fold(Seq.empty)(_++_)
res14: Seq[Int] = List(1, 2)

scala> List[Int]().map(Seq(_)).fold(Seq.empty)(_++_)
res15: Seq[Int] = List()

编辑:您的示例中的问题似乎与方法之间删除点(.)字符有关。如果你保留它们,一切正常:

scala> List(1,2,3).map(i => node).fold(NodeSeq.Empty)(_ ++ _)
res57: scala.xml.NodeSeq = NodeSeq(<li><a href="/foo">Link</a></li>, <li><a href="/foo">Link</a></li>, <li><a href="/foo">Link</a></li>)