你如何在 Scala 中覆盖 def toString 来打印 List[List[Int]?
How do you override def toString in Scala to print a List[List[Int]?
我正在尝试编写一个函数来覆盖 Scala 中的 toString
函数。我有一个要打印的列表列表 (List[List[Int]]
)。 List[List[Int]]
表示数独网格。每个 List[Int]
代表一个特定的行。 override 函数应该打印网格,用 '_' 替换 '0'。我应该递归地实现一切。以下是我的代码:
override def toString() = {
def innerFn(li: List[Int], s:String): String = {
if (li.tail.isEmpty) s+"\n"
else {
if (li.head == 0) innerFn(li.tail,s+"_ ")
else innerFn(li.tail,s+li.head+" ")
}
}
def outerFn(li: List[List[Int]], s: String): String = {
if (li.tail.isEmpty) s
else {
if (li.tail.head.isEmpty) s
else innerFn(li.head,s)
}
}
outerFn(grid,"")
}
我相信我的 "innerFn()" 工作正常,因为它正在打印我需要的 List[Int]。但是,出于某种原因,只打印了第一行(或 List[List[Int]]
的第一个元素)。我看不到我错过了什么。
在 Scala 中,我们正在创建包装器来覆盖特定类型混合的基本方法:
object Sudoku {
implicit class GroupStr[X](xs: Seq[X]) {
def groupStr(sep: String): String =
xs.grouped(3).map(
_.mkString(sep, sep, sep)
).mkString
}
}
case class Sudoku(grid: List[List[Int]]) {
import Sudoku._
def lineSep = ("-" * 9).toList.groupStr("+") + "\n"
override def toString = grid.map(_.groupStr("|") + "\n").groupStr(lineSep)
}
现在你可以验证
println(Sudoku(List.range(0, 9).map(
i => List.range(0, 9).map( j => (i + j) % 9 + 1))))
打印
+-+-+-++-+-+-++-+-+-+
|1|2|3||4|5|6||7|8|9|
+-+-+-++-+-+-++-+-+-+
|2|3|4||5|6|7||8|9|1|
+-+-+-++-+-+-++-+-+-+
|3|4|5||6|7|8||9|1|2|
+-+-+-++-+-+-++-+-+-+
+-+-+-++-+-+-++-+-+-+
|4|5|6||7|8|9||1|2|3|
+-+-+-++-+-+-++-+-+-+
|5|6|7||8|9|1||2|3|4|
+-+-+-++-+-+-++-+-+-+
|6|7|8||9|1|2||3|4|5|
+-+-+-++-+-+-++-+-+-+
+-+-+-++-+-+-++-+-+-+
|7|8|9||1|2|3||4|5|6|
+-+-+-++-+-+-++-+-+-+
|8|9|1||2|3|4||5|6|7|
+-+-+-++-+-+-++-+-+-+
|9|1|2||3|4|5||6|7|8|
+-+-+-++-+-+-++-+-+-+
另一种方法是使用像 scalaz.Show
also see here
这样的类型类
递归形式
val grid: List[List[Int]] = List(List(1, 2, 3), List(2, 3, 4))
def toString() = {
def innerFn(li: List[Int]): String = {
li match {
case x :: xs => li.mkString(",")
case Nil => ""
}
}
def outerFn(li: List[List[Int]]): String = {
li match {
case x :: xs if (!xs.isEmpty) => innerFn(x) + "\n" + outerFn(xs)
case x :: Nil => innerFn(x)
case Nil => ""
}
}
outerFn(grid)
}
我正在尝试编写一个函数来覆盖 Scala 中的 toString
函数。我有一个要打印的列表列表 (List[List[Int]]
)。 List[List[Int]]
表示数独网格。每个 List[Int]
代表一个特定的行。 override 函数应该打印网格,用 '_' 替换 '0'。我应该递归地实现一切。以下是我的代码:
override def toString() = {
def innerFn(li: List[Int], s:String): String = {
if (li.tail.isEmpty) s+"\n"
else {
if (li.head == 0) innerFn(li.tail,s+"_ ")
else innerFn(li.tail,s+li.head+" ")
}
}
def outerFn(li: List[List[Int]], s: String): String = {
if (li.tail.isEmpty) s
else {
if (li.tail.head.isEmpty) s
else innerFn(li.head,s)
}
}
outerFn(grid,"")
}
我相信我的 "innerFn()" 工作正常,因为它正在打印我需要的 List[Int]。但是,出于某种原因,只打印了第一行(或 List[List[Int]]
的第一个元素)。我看不到我错过了什么。
在 Scala 中,我们正在创建包装器来覆盖特定类型混合的基本方法:
object Sudoku {
implicit class GroupStr[X](xs: Seq[X]) {
def groupStr(sep: String): String =
xs.grouped(3).map(
_.mkString(sep, sep, sep)
).mkString
}
}
case class Sudoku(grid: List[List[Int]]) {
import Sudoku._
def lineSep = ("-" * 9).toList.groupStr("+") + "\n"
override def toString = grid.map(_.groupStr("|") + "\n").groupStr(lineSep)
}
现在你可以验证
println(Sudoku(List.range(0, 9).map(
i => List.range(0, 9).map( j => (i + j) % 9 + 1))))
打印
+-+-+-++-+-+-++-+-+-+
|1|2|3||4|5|6||7|8|9|
+-+-+-++-+-+-++-+-+-+
|2|3|4||5|6|7||8|9|1|
+-+-+-++-+-+-++-+-+-+
|3|4|5||6|7|8||9|1|2|
+-+-+-++-+-+-++-+-+-+
+-+-+-++-+-+-++-+-+-+
|4|5|6||7|8|9||1|2|3|
+-+-+-++-+-+-++-+-+-+
|5|6|7||8|9|1||2|3|4|
+-+-+-++-+-+-++-+-+-+
|6|7|8||9|1|2||3|4|5|
+-+-+-++-+-+-++-+-+-+
+-+-+-++-+-+-++-+-+-+
|7|8|9||1|2|3||4|5|6|
+-+-+-++-+-+-++-+-+-+
|8|9|1||2|3|4||5|6|7|
+-+-+-++-+-+-++-+-+-+
|9|1|2||3|4|5||6|7|8|
+-+-+-++-+-+-++-+-+-+
另一种方法是使用像 scalaz.Show
also see here
递归形式
val grid: List[List[Int]] = List(List(1, 2, 3), List(2, 3, 4))
def toString() = {
def innerFn(li: List[Int]): String = {
li match {
case x :: xs => li.mkString(",")
case Nil => ""
}
}
def outerFn(li: List[List[Int]]): String = {
li match {
case x :: xs if (!xs.isEmpty) => innerFn(x) + "\n" + outerFn(xs)
case x :: Nil => innerFn(x)
case Nil => ""
}
}
outerFn(grid)
}