在Scala中脱离双重foreach

时间:2016-09-13 22:14:13

标签: scala

我必须根据内部设置项中的字段值返回true或false。我的循环如下

myChoice.category.foreach(category => {
  category.flavours.foreach(flavour=> {
    if (flavour.available) true
  })
})
false

一旦我确实可用,它就会打破并返回true,但它一直都是假的。有什么建议吗?

3 个答案:

答案 0 :(得分:6)

我没有使用您的数据集,但也许这可能会这样做。

myChoice.category.exists(_.flavours.exists(_.available))

答案 1 :(得分:3)

Scala没有continuebreak。因为它是一个功能齐全的语言,所以每个表达式(包括一个循环)都必须有一个值。此外,它试图打破初始化变量的命令式风格,并在循环过程中对它们进行变异。相反,scala鼓励您使用功能样式,即使用适用于整个数据结构的方法来转换/搜索所需的结果。

对于您的情况,您显然希望查看是否有任何风格的available字段设置为true。因此,您可以将整个嵌套集合flatMap映射到布尔列表,并获取整个集合的or

val anyAvaliable = myChoice.category.flatMap(a => a.flavours).reduce( (flavour1,flavour2) => flavour1.available || flavour2.available)

jwvh的解决方案更加简洁。有许多方法可以完成基本相同的事情。不要对抗语言,让它为你而战!

答案 2 :(得分:1)

免责声明:以下解决方案是为了完整性而提供的,但对于这种情况,jwvh的答案应该是首选,一般而言,有更好的选择。特别要注意,lambda中的return是使用异常实现的,所以1)它可能比普通的方法调用更糟糕; 2)如果你不小心你可能会意外地抓住它。

如果这是您在方法中需要做的最后一件事,您可以使用return

myChoice.category.foreach(category => {
  category.flavours.foreach(flavour=> {
    if (flavour.available) return true
  })
})
false

如果不是,您可以提取方法(包括本地方法):

def foo = {
  ...

  val myChoice = ...

  def hasAvailableFlavorsMethod() = {
    myChoice.category.foreach(category => {
      category.flavours.foreach(flavour=> {
        if (flavour.available) return true
      })
    })
    false
  }

  val hasAvailableFlavors = hasAvailableFlavorsMethod()

  ...
}