我想知道在List
上如果它不为空则应用某些操作的惯用方法是什么,如果列表为空则返回空List
(Nil
)。
val result= myList match {
case Nil => Nil // this one looks bad for me
case nonEmpty => myService.getByFilters(nonEmpty)
}
在列表上使用map
操作会触发循环,但我想为map
类型获得与Option
相同的结果 - 即如果List
只执行一次操作非空,如果List
为空,则不执行任何操作
答案 0 :(得分:3)
我认为你的设计也许并不合适。您应该只能将任何列表传递到getByFilters
函数,它应该只处理任何长度的列表。所以不应该进行这类检查。
如果无法进行设计更改,if
:
val result = if(myList.isEmpty) Nil else myService.getByFilters(myList)
这是惯用的,因为if
返回值。也许还有其他干净的方式,我不知道。
如果您只想要非空列表参数,可以使用HList
,或者您可以使用此技巧:
def takesNonEmptyList[T](head: T, tail: T *): List[T] = head :: tail.toList
你可以做一些虚假的事情,使它看起来像惯用语,但我不推荐它。这是不清楚和不必要的并发症:
def getByFilters(xs: List[Int]) = xs.filter(_ % 2 == 0)
val res = l.headOption.map(_ :: l.tail).map(getByFilters).getOrElse(Nil)
println(res)
打印List(2, 4)
答案 1 :(得分:0)
如果你真的想要它,你可以实现自己的语义:
implicit class MySpecialList[T](xs: List[T]) {
def mapIfNotEmpty[R](f: List[T] ⇒ List[R]): List[R] =
if (xs.isEmpty) Nil else f(xs)
}
def getStuff(xs: List[Int]) = xs.map(_ + " OK")
val x: List[Int] = List(1,2,3)
val y: List[Int] = List()
def main(args: Array[String]): Unit = {
val xx = x.mapIfNotEmpty(getStuff) // List("1 OK", "2 OK", "3 OK")
val yy = y.mapIfNotEmpty(getStuff) // List()
}
答案 2 :(得分:0)
headOption
中有方法List
,因此您可以使用选项语义将List
提升为Option[List]
:
import scala.collection.TraversableLike
implicit class TraversableOption[T <: TraversableLike[_, T]](traversable: T) {
def opt: Option[T] = traversable.headOption.map(_ => traversable)
}
您可以将其用作:
val result = myList.opt.fold[List[Int]](Nil)(myService.getByFilters)
答案 3 :(得分:0)
通过单独调用每个过滤器服务,
myList.flatMap(filter => myService.getByFilters(List(filter)))
如果myList
为空,则会获得一个空列表。如果性能可能是一个问题,请考虑使用
myList.par