我最近开始学习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
}
我是否正确理解isMiddleCell
应该实现为:
def isMiddleCell() = {
this match {
case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
case _ => false
}
答案 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))
在这个例子中,这允许你对两个数字进行加法,而不知道它们是否确实存在。