evi*_*ead 14 rendering scala console-application tabular
我需要在控制台中显示一个表.
我的简单解决方案,如果你称之为"解决方案",如下:
  override def toString() = {
    var res = "\n"
      var counter = 1;
      res += stateDb._1 + "\n"
      res += "  +----------------------------+\n"
      res += "  +     State Table            +\n"
      res += "  +----------------------------+\n"
      for (entry <- stateDb._2) {
        res += "  | " + counter + "\t | " + entry._1 + " | " + entry._2 + " |\n"
        counter += 1;
      }
      res += "  +----------------------------+\n"
      res += "\n"
    res
  }
Run Code Online (Sandbox Code Playgroud)
我们不必争论这个
实际上,这个问题被要求用于C#,但我也想知道Scala的一个很好的解决方案.
那么在Scala中将这样的表绘制到控制台是什么(很好/好/简单/无论如何)呢?
-------------------------------------------------------------------------
|    Column 1     |    Column 2     |    Column 3     |    Column 4     |
-------------------------------------------------------------------------
|                 |                 |                 |                 |
|                 |                 |                 |                 |
|                 |                 |                 |                 |
-------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
    Dun*_*gor 32
我从当前项目中提取了以下内容:
object Tabulator {
  def format(table: Seq[Seq[Any]]) = table match {
    case Seq() => ""
    case _ => 
      val sizes = for (row <- table) yield (for (cell <- row) yield if (cell == null) 0 else cell.toString.length)
      val colSizes = for (col <- sizes.transpose) yield col.max
      val rows = for (row <- table) yield formatRow(row, colSizes)
      formatRows(rowSeparator(colSizes), rows)
  }
  def formatRows(rowSeparator: String, rows: Seq[String]): String = (
    rowSeparator :: 
    rows.head :: 
    rowSeparator :: 
    rows.tail.toList ::: 
    rowSeparator :: 
    List()).mkString("\n")
  def formatRow(row: Seq[Any], colSizes: Seq[Int]) = {
    val cells = (for ((item, size) <- row.zip(colSizes)) yield if (size == 0) "" else ("%" + size + "s").format(item))
    cells.mkString("|", "|", "|")
  }
  def rowSeparator(colSizes: Seq[Int]) = colSizes map { "-" * _ } mkString("+", "+", "+")
}
scala> Tabulator.format(List(List("head1", "head2", "head3"), List("one", "two", "three"), List("four", "five", "six")))
res1: java.lang.String = 
+-----+-----+-----+
|head1|head2|head3|
+-----+-----+-----+
|  one|  two|three|
| four| five|  six|
+-----+-----+-----+
Run Code Online (Sandbox Code Playgroud)
        小智 6
如果你想要它更紧凑一些。奖励:左对齐并在两侧填充 1 个字符。基于邓肯·麦格雷戈的回答(/sf/answers/527973351/):
def formatTable(table: Seq[Seq[Any]]): String = {
  if (table.isEmpty) ""
  else {
    // Get column widths based on the maximum cell width in each column (+2 for a one character padding on each side)
    val colWidths = table.transpose.map(_.map(cell => if (cell == null) 0 else cell.toString.length).max + 2)
    // Format each row
    val rows = table.map(_.zip(colWidths).map { case (item, size) => (" %-" + (size - 1) + "s").format(item) }
      .mkString("|", "|", "|"))
    // Formatted separator row, used to separate the header and draw table borders
    val separator = colWidths.map("-" * _).mkString("+", "+", "+")
    // Put the table together and return
    (separator +: rows.head +: separator +: rows.tail :+ separator).mkString("\n")
  }
}
scala> formatTable(Seq(Seq("head1", "head2", "head3"), Seq("one", "two", "three"), Seq("four", "five", "six")))
res0: String =
+-------+-------+-------+
| head1 | head2 | head3 |
+-------+-------+-------+
| one   | two   | three |
| four  | five  | six   |
+-------+-------+-------+
Run Code Online (Sandbox Code Playgroud)