Scala嵌套在对象

时间:2016-02-10 22:26:27

标签: scala pattern-matching

我最近开始学习scala广告尝试熟悉一个简单的演示程序。

我想检查一个单元格是否包含所有邻居。在java中,这可以通过以下方式完成:

public boolean hasFullNeighbourhood() {
    if (top != null && bottom != null && left != null && right != null && 
            top.getLeft() != null && top.getRight() 
            != null && bottom.getLeft() != null 
            && bottom.getRight() != null)
        return true;
    else
        return false;
}

Cell定义为:

class Cell(
            val x: Int,
            val y: Int,
            val left: Option[Cell],
            val right: Option[Cell],
            val top: Option[Cell],
            val bottom: Option[Cell],
            var isPainted: Boolean)

如何在scala中定义完整的邻域? 我开始喜欢:

    def hasFullNeighbourhood(r:Int): Boolean={
        if(r ==0)
          return true
        if (List(top, bottom, left, right).forall(_.isDefined))
          return  true
        else
          return false
  }

但是如何访问其余部分(x.top, x.bottom, x.left, x.right)并检查这些是否为空/可选对我来说还不清楚。

我认为像top.foreach()这样的东西是可能的 - 但如果添加到选项列表中,如果返回none则不会失败。

修改

我将我的课程重新定义为案例类:

case class Cell(
            val x: Int,
            val y: Int,
            val left: Option[Cell],
            val right: Option[Cell],
            val top: Option[Cell],
            val bottom: Option[Cell],
            var isPainted: Boolean)

这是否意味着

  def isMiddleCell()={
    if(List(top, bottom, left, right).forall(_.isDefined))
      true
    else
      false
  }

可以改写为:

  def isMiddleCell(c: Cell) = c match {
    case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
    case _ => false
  }

这仍然有点奇怪,因为我想要检查给定的单元格,如果这个是中间单元格,而不指定Cell.isMiddleCell(givenCell)而是givenCell.isMiddleCell()

然而要实施

def hasFullNeughbourhood(radius:Int)正确地不需要更多的陈述,因为我不仅要检查直接邻居。对我来说,目前还不清楚如何获取这些。在java中,我会使用x.getLeft()和递归x.getLeft().hasFullNeighbourhood(r - 1)

def hasFullNeighbourhood(c: Cell) = c match {
    case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
    case _ => false
  }

EDIT2

我是否正确理解isMiddleCell应该实现为:

  def isMiddleCell() = {
    this match {
      case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
      case _ => false
    }

1 个答案:

答案 0 :(得分:1)

通常有很好的方法可以对Scala中的容器内容执行操作:通过模式匹配进行映射或分解。如果您不习惯函数式编程,则模式匹配在Option中更直观。

为了使模式匹配更容易,您应该将您的单元类定义为案例类。这为您提供模式匹配,而无需自己实现任何内容,并使下一个示例更好。对于简单的数据模型类,案例类总是一个好主意。

def hasFullNeighbourhood(c: Cell) = c match {
  case Cell(_,_,Some(top),Some(bottom),Some(left),Some(right),_) => true
  case _ => false

我在变量名称的左下角等等,因为您可以使用它们对这些值执行某些操作。但是因为你不需要它们用于这种方法我也可以写_。如果您还不知道模式匹配,请阅读它。没有它的Scala并不好玩。

另一种方式是使用地图。如果你想对“容器”中的东西进行一些计算并将它放回到同一种容器中,这只是有趣的:

val possiblyANumber1 = Some(5)
val possiblyANumber2 = Some(5)
val possiblyANumber3 = possiblyANumber1.flatMap(x => possiblyANumber2.map(y => x + y))

在这个例子中,这允许你对两个数字进行加法,而不知道它们是否确实存在。