On this page:
table?
table
columns
row
table-ref
table-rows-ref
table-columns-ref
table-size
4.14.1 Table Iteration and Comprehensions
for/  table
for*/  table
in-table
into-table
7.7

4.14 Tables

 (require rebellion/collection/table) package: rebellion

A table is a data structure made up of a collection of rows. Tables contain a list of column names — represented by keywords — and each row has a value for each column in the row’s table. This makes rows similar to records, with the constraint that all the row records in a table have the same keys. Tables maintain rows as lists, not sets, so the order of rows in a table is significant and duplicate rows are allowed. Tables implement the sequence interface, and can be iterated as a sequence of rows.

procedure

(table? v)  boolean?

  v : any/c
A predicate for tables.

syntax

(table (columns column-kw ...) (row row-value ...) ...)

Constructs a table containing all of the given rows and whose columns are named by the given column-kws. Row values are given by-position and there must be exactly one value for each column-kw.

Example:
> (table (columns #:name #:population #:capital-city)
         (row "Argentina" 43800000 "Buenos Aires")
         (row "Greece" 10800000 "Athens")
         (row "Nigeria" 198600000 "Abuja")
         (row "Japan" 126400000 "Tokyo"))

(table

 (columns #:capital-city #:name #:population)

 (row "Buenos Aires" "Argentina" 43800000)

 (row "Athens" "Greece" 10800000)

 (row "Abuja" "Nigeria" 198600000)

 (row "Tokyo" "Japan" 126400000))

syntax

columns

syntax

row

Syntactic forms recognized by table. Both columns and row are meaningless on their own; they can only be used in a table expression.

procedure

(table-ref tab pos column)  any/c

  tab : table?
  pos : natural?
  column : keyword?
Returns the value for column in the row at position pos in tab.

Examples:
> (define countries
    (table (columns #:name #:population #:capital-city)
           (row "Argentina" 43800000 "Buenos Aires")
           (row "Greece" 10800000 "Athens")
           (row "Nigeria" 198600000 "Abuja")
           (row "Japan" 126400000 "Tokyo")))
> (table-ref countries 3 '#:name)

"Japan"

procedure

(table-rows-ref tab pos)  record?

  tab : table?
  pos : natural?
Returns the row in tab at position pos, as a record mapping column names to their values in the row.

Examples:
> (define countries
    (table (columns #:name #:population #:capital-city)
           (row "Argentina" 43800000 "Buenos Aires")
           (row "Greece" 10800000 "Athens")
           (row "Nigeria" 198600000 "Abuja")
           (row "Japan" 126400000 "Tokyo")))
> (table-rows-ref countries 2)

(record #:capital-city "Abuja" #:name "Nigeria" #:population 198600000)

procedure

(table-columns-ref tab column)  immutable-vector?

  tab : table?
  column : keyword?
Returns a vector of all the values for column in tab, with each element corresponding to one row in tab.

Examples:
> (define countries
    (table (columns #:name #:population #:capital-city)
           (row "Argentina" 43800000 "Buenos Aires")
           (row "Greece" 10800000 "Athens")
           (row "Nigeria" 198600000 "Abuja")
           (row "Japan" 126400000 "Tokyo")))
> (table-columns-ref countries '#:capital-city)

'#("Buenos Aires" "Athens" "Abuja" "Tokyo")

procedure

(table-size tab)  natural?

  tab : table?
Returns the number of rows in tab.

Examples:
(define countries
  (table (columns #:name #:population #:capital-city)
         (row "Argentina" 43800000 "Buenos Aires")
         (row "Greece" 10800000 "Athens")
         (row "Nigeria" 198600000 "Abuja")
         (row "Japan" 126400000 "Tokyo")))

 

> (table-size countries)

4

4.14.1 Table Iteration and Comprehensions

syntax

(for/table (for-clause ...) body-or-break ... body)

 
  body : record?
Iterates like for, but each body must evaluate to a record and the resulting records are collected into a table. All body records must have the same keys. If body is never evaluated, for instance because the loop iterates over an empty collection, then an empty table with no rows and no columns is returned.

Example:
> (for/table ([god (in-list (list "Zeus" "hera" "hades" "Athena" "PosEIdon"))])
    (define name (string-titlecase god))
    (record #:name name
            #:correct-case? (equal? name god)
            #:name-length (string-length god)))

(table

 (columns #:correct-case? #:name #:name-length)

 (row #t "Zeus" 4)

 (row #f "Hera" 4)

 (row #f "Hades" 5)

 (row #t "Athena" 6)

 (row #f "Poseidon" 8))

syntax

(for*/table (for-clause ...) body-or-break ... body)

 
  body : record?
Like for/table, but iterates like for*.

procedure

(in-table tab)  (sequence/c record?)

  tab : table?
Returns a sequence that iterates through each row of tab. Tables already implement the sequence interface, but using this function in a for form may perform better and give clearer error messages.

A reducer that reduces records into a table, in the same manner as for/table.

Example:
> (reduce into-table
          (record #:person "Sam"
                  #:age 78
                  #:favorite-color 'green)
          (record #:person "Jamie"
                  #:age 30
                  #:favorite-color 'purple)
          (record #:person "Ned"
                  #:age 40
                  #:favorite-color 'red))

(table

 (columns #:age #:favorite-color #:person)

 (row 78 'green "Sam")

 (row 30 'purple "Jamie")

 (row 40 'red "Ned"))