alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (TableDef.scala)

This example Scala source code file (TableDef.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

any, column, column, int, int, list, map, seq, seq, string, string, t, table, tabledef

The Scala TableDef.scala source code

package scala.tools.nsc
package util

import TableDef._

/** A class for representing tabular data in a way that preserves
 *  its inner beauty.  See Exceptional for an example usage.
 *  One creates an instance of TableDef by defining the columns of
 *  the table, then uses that to create an instance of Table by
 *  passing in a sequence of rows.
 */
class TableDef[T](_cols: Column[T]*) {
  /** These operators are about all there is to it.
   *
   *  ~   appends a column to the table
   *  >>  creates a right-justified column and appends it
   *  <<  creates a left-justified column and appends it
   *  >+  specifies a string to separate the previous column from the next.
   *      if none is specified, a space is used.
   */
  def ~(next: Column[T])            = retThis(cols :+= next)
  def >>(pair: (String, T => Any))  = this ~ Column(pair._1, pair._2, false)
  def <<(pair: (String, T => Any))  = this ~ Column(pair._1, pair._2, true)
  def >+(sep: String)               = retThis(separators += ((cols.size - 1, sep)))

  /** Below this point should all be considered private/internal.
   */
  private var cols: List[Column[T]] = _cols.toList
  private var separators: Map[Int, String] = Map()

  def defaultSep(index: Int) = if (index > (cols.size - 2)) "" else " "
  def sepAfter(i: Int): String = separators.getOrElse(i, defaultSep(i))
  def sepWidths = cols.indices map (i => sepAfter(i).length)  
  
  def columns = cols
  def colNames = cols map (_.name)
  def colFunctions = cols map (_.f)
  def colApply(el: T) = colFunctions map (f => f(el))
  def retThis(body: => Unit): this.type = { body ; this }
  
  class Table(val rows: Seq[T]) extends Seq[T] {
    def iterator          = rows.iterator
    def apply(index: Int) = rows(index)
    def length            = rows.length
    
    def maxColWidth(col: Column[T]) = col.name +: (rows map col.f) map (_.toString.length) max
    def specs = cols map (_ formatSpec rows)
    
    val colWidths   = cols map maxColWidth
    val rowFormat   = mkFormatString(sepAfter)
    val headFormat  = mkFormatString(i => " " * sepWidths(i))
    val argLists    = rows map colApply

    val headers = List(
      headFormat.format(colNames: _*),
      (colWidths, sepWidths).zipped map ((w1, w2) => "-" * w1 + " " * w2) mkString
    )

    def mkFormatString(sepf: Int => String): String =
      specs.zipWithIndex map { case (c, i) => c + sepf(i) } mkString

    def pp(): Unit = allToSeq foreach println
    
    def toFormattedSeq = argLists map (xs => rowFormat.format(xs: _*))
    def allToSeq = headers ++ toFormattedSeq
    
    override def toString = allToSeq mkString "\n"
  }
  
  def formatterFor(rows: Seq[T]): T => String = {
    val formatStr = new Table(rows).rowFormat
    
    x => formatStr.format(colApply(x) : _*)
  }

  def table(rows: Seq[T]) = new Table(rows)
  
  override def toString = cols.mkString("TableDef(", ", ", ")")
}

object TableDef {    
  case class Column[-T](name: String, f: T => Any, left: Boolean) {
    def maxWidth(elems: Seq[T]): Int = name +: (elems map f) map (_.toString.length) max
    def formatSpec(elems: Seq[T]): String = {
      val justify = if (left) "-" else ""
      "%" + justify + maxWidth(elems) + "s"
    }
    override def toString = {
      val justify = if (left) "<<" else ">>"
      justify + "(" + name + ")"
    }
  }
  
  def apply[T](cols: Column[T]*) = new TableDef[T](cols: _*)
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala TableDef.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.