Форматирование в виде таблицы в Scala


Я пытаюсь получить мою голову в игре Скала, и приветствуем обратную связь на следующий код, который создает таблицу с данными.

class TabulatorTest extends FunSuite with ShouldMatchers {

  test("format") {
    Tabulator.format(List(
      List("head1", "head2", "head3"),
      List("one", "two", "three"), 
      List("four", "five", "six"))) should be ("""
+-----+-----+-----+
|head1|head2|head3|
+-----+-----+-----+
|  one|  two|three|
| four| five|  six|
+-----+-----+-----+
""".trim)
  }

  test("format empty") {
    Tabulator.format(List()) should be ("")
    Tabulator.format(List(List())) should be ("""
++
||
++
++
""".trim)
  }

  test("uneven rows") {
    try {
      Tabulator.format(List(    
        List("head1", "head2", "head3"),
        List("one", "two")))
      fail()
    } catch {
      case e: IllegalArgumentException => 
    }
  }
}

object Tabulator {

  def format(table: Seq[Seq[Any]]) = table match {
    case Seq() => ""
    case _ => 
      val cellSizes = for (row <- table) yield 
        (for (cell <- row) yield 
          if (cell == null) 0 else cell.toString.length)
      val colSizes = for (col <- cellSizes.transpose) yield col.max
      val rows = for (row <- table) yield formatRow(row, colSizes)
      formatRows(rowSeparator(colSizes), rows)
  }

  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 formatRows(rowSeparator: String, rows: Seq[String]): String = (
    rowSeparator :: 
    rows.head :: 
    rowSeparator :: 
    rows.tail.toList ::: 
    rowSeparator :: 
    List()).mkString("\n")


  private def rowSeparator(colSizes: Seq[Int]) =
    colSizes map { "-" * _ } mkString("+", "+", "+")
}


428
2
задан 3 октября 2011 в 12:10 Источник Поделиться
Комментарии
1 ответ

Я не могу помочь много. Только некоторые синтаксические подсказки:

object Tabulator {

def format(table: Seq[Seq[Any]]) =
if (table.isEmpty) ""
else {
def cellSize(cell: Any) =
cell.toString.length

val cellSizes =
table map { _ map cellSize }
val colSizes =
cellSizes.transpose map { _.max }
val rows =
table map formatRow(colSizes)

formatRows(rowSeparator(colSizes), rows)
}

def formatRow(colSizes: Seq[Int])(row: Seq[Any]) = {
val cells =
for ((item, size) <- row zip colSizes) yield
if (size == 0) "" else "%"+size+"s" format item
cells mkString ("|", "|", "|")
}

def formatRows(rowSeparator: String, rows: Seq[String]): String = (
rowSeparator
:: rows.head
:: rowSeparator
:: rows.tail.toList
::: rowSeparator
:: Nil
) mkString "\n"

private def rowSeparator(colSizes: Seq[Int]) =
colSizes map { "-"*_ } mkString ("+", "+", "+")
}

Я удалил null-проверка на размер ячейки, поскольку нуль не знакомы в Scala. Если вам обязательно нужен нуль, то восстановить чек.

3
ответ дан 3 октября 2011 в 07:10 Источник Поделиться