13

是否有更短/更好的方法来执行以下操作:

mySeq.map { elmt => 
    // do stuff
}   

if (mySeq.isEmpty) {
    // some other stuff
}

Ps:我正在使用 PlayFramework,这意味着在模板中使用,所以如果我错过了任何“帮助者”,我会很高兴发现那些 ;)

4

5 回答 5

15

这个怎么样?

mySeq.headOption.map { _ =>
  mySeq.map { elmt => 
    // do stuff
  }
}.getOrElse {
  // some other stuff
}
于 2012-08-21T08:56:56.700 回答
7

您可以使用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)
于 2012-08-21T08:43:04.450 回答
4

我最近提供了一个助手,它仅在给定序列非空时生成一些 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
  }
}
于 2012-08-21T10:13:09.360 回答
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")

如果列表为空,它将导致 aString 1, 2, 3并且会导致 a 。String Empty list

于 2012-08-21T13:08:53.953 回答
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
  }
于 2019-08-01T15:22:04.553 回答