你如何在 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)
  }