Scala - 'for-yield'条款对某些条件没有任何影响吗?

poc*_*all 12 scala yield-keyword

在Scala语言中,我想编写一个在给定范围内产生奇数的函数.迭代偶数时,该函数会打印一些日志.该函数的第一个版本是:

def getOdds(N: Int): Traversable[Int] = {
  val list = new mutable.MutableList[Int]
  for (n <- 0 until N) {
    if (n % 2 == 1) {
      list += n
    } else {
      println("skip even number " + n)
    }
  }
  return list
}
Run Code Online (Sandbox Code Playgroud)

如果省略打印日志,则实现变得非常简单:

def getOddsWithoutPrint(N: Int) =
  for (n <- 0 until N if (n % 2 == 1)) yield n
Run Code Online (Sandbox Code Playgroud)

但是,我不想错过记录部分.如何更紧凑地重写第一个版本?如果它可以被重写类似于这将是伟大的:

def IWantToDoSomethingSimilar(N: Int) =
  for (n <- 0 until N) if (n % 2 == 1) yield n else println("skip even number " + n)
Run Code Online (Sandbox Code Playgroud)

Lui*_*hys 9

def IWantToDoSomethingSimilar(N: Int) = 
  for {
    n <- 0 until N
    if n % 2 != 0 || { println("skip even number " + n); false }
  } yield n
Run Code Online (Sandbox Code Playgroud)

但是使用filter而不是for表达式会稍微简单一些.


jwi*_*ndy 6

我想保持你的traitement顺序(按顺序处理赔率和平均值,而不是单独处理),你可以使用类似的东西(编辑):

def IWantToDoSomethingSimilar(N: Int) =
  (for (n <- (0 until N)) yield {
    if (n % 2 == 1) {
        Option(n) 
    } else {
        println("skip even number " + n)
        None
    }
  // Flatten transforms the Seq[Option[Int]] into Seq[Int]
  }).flatten
Run Code Online (Sandbox Code Playgroud)

编辑遵循相同的概念,更短的解决方案:

def IWantToDoSomethingSimilar(N: Int) = 
    (0 until N) map {
        case n if n % 2 == 0 => println("skip even number "+ n)
        case n => n
    } collect {case i:Int => i}
Run Code Online (Sandbox Code Playgroud)