是否有更短/更好的方法来执行以下操作:
mySeq.map { elmt =>
// do stuff
}
if (mySeq.isEmpty) {
// some other stuff
}
Ps:我正在使用PlayFramework,这是用于模板,所以如果有任何“助手”我错过了,我会很高兴发现那些;)
答案 0 :(得分:13)
这个怎么样?
mySeq.headOption.map { _ =>
mySeq.map { elmt =>
// do stuff
}
}.getOrElse {
// some other stuff
}
答案 1 :(得分:6)
您可以使用match
:
l match {
case l if !l.isEmpty => l.map{ // do stuff }
case _ => // some other stuff
}
List
:
l match {
case h :: t => l.map{ // do stuff }
case _ => // some other stuff
}
或者,您可以定义自己的方法:
import scala.collection.generic.CanBuildFrom
import scala.collection.TraversableLike
class FoldEmpty[T, S[T] <: TraversableLike[T, S[T]]](l: S[T]){
def foldEmpty[B, That](notEmpty: T => B, empty: => That)(implicit cbf: CanBuildFrom[S[T], B, That]): That =
l match {
case t if !t.isEmpty => l map notEmpty
case _ => empty
}
}
implicit def seqToFoldEmpty[T, S[T] <: TraversableLike[T, S[T]]](l: S[T]) = new FoldEmpty(l)
用法:
scala> IndexedSeq(1, 2, 3).foldEmpty( _ + 1 , IndexedSeq(-1))
res0: IndexedSeq[Int] = Vector(2, 3, 4)
scala> IndexedSeq[Int]().foldEmpty( _ + 1 , Seq(-1))
res1: Seq[Int] = List(-1)
答案 2 :(得分:4)
我最近gisted一个助手,只有在给定的序列非空时才生成一些HTML。将这种轻微变化放在文件中,例如Helpers.scala
:
package views.html.helper
import play.api.templates.Html
object nonEmptyOrElse {
def apply[T <: Seq[_]](t: T)(nonEmptyBlock: (T) => Html)(emptyBlock: => Html) = {
if (t.nonEmpty) nonEmptyBlock(t) else emptyBlock
}
}
在模板中使用它:
@nonEmptyOrElse(mySeq) { seq =>
//doSomething with entire seq
} {
// do something else
}
编辑:这是地图每个元素的版本:
object mapOrElse {
def apply[T](t: Seq[T])(nonEmptyBlock: (T) => Html)(emptyBlock: => Html) = {
if (t.nonEmpty) t.map(nonEmptyBlock(_)) else emptyBlock
}
}
答案 3 :(得分:2)
在范围内具有以下简单扩展名:
(对于Scala 2.10):
implicit class AnyExtensions[A] ( val x : A ) extends AnyVal {
def asSatisfying(p: A => Boolean): Option[A] =
if (p(x)) Some(x) else None
}
(对于Scala 2.9):
implicit def anyExtensions[A] (x : A) = new {
def asSatisfying(p: A => Boolean): Option[A] =
if (p(x)) Some(x) else None
}
您将能够按如下方式重写代码:
mySeq
.asSatisfying{_.nonEmpty}
.map{
_.map{elmt =>
// do stuff
}
}
.getOrElse{
// some other stuff
}
在我的实践中,这个扩展证明适用于很多情况并且非常有用。当您意识到在表达式的中间需要if
语句时,它会表现出色,如果没有此扩展,则需要您引入临时变量。这是一个例子:
List(1, 2, 3).mkString(", ").asSatisfying{_.nonEmpty}.getOrElse("Empty list")
如果列表为空,则会产生String
1, 2, 3
并产生String
Empty list
。
答案 4 :(得分:0)
这是一个有用的值类,如果Seq.isEmpty可以将Seq [A]转换为None,否则将其包装在Some [Seq [A]]中。
对于Scala 2.10:
/**
* A value type class to add some useful utility methods to Seq
*
* @param underlying The Seq to augment.
*/
implicit class SeqExt[+A](private val underlying: Seq[A]) extends AnyVal {
/** If this Seq is empty, returns None, otherwise builds a new collection by
* applying a function to all elements of this immutable sequence, and wraps
* the Seq in an Option.
*
* @tparam B The element type of the returned collection.
* @param f The function to apply to each element.
* @return If this Seq is empty, returns None, otherwise builds a new collection by
* applying a function to all elements of this immutable sequence, and wraps
* the Seq in an Option.
*/
def mapOption[B](f: (A) ⇒ B): Option[Seq[B]] = {
if(underlying.isEmpty) None else Some(underlying.map(f))
}
}
用法(如您的示例):
mySeq
.mapOption { elmt =>
// do stuff to each element if mySeq.nonEmpty
}
.getOrElse {
// some other stuff if mySeq.isEmpty
}