====================================================================
Table examples
====================================================================

The Table constructor provides a general structure for associative
storage.  This type provides hash tables in which data objects can be
saved according to keys of any type.  For a given table, specific
types must be chosen for the keys and entries.

In this example the keys to the table are polynomials with integer
coefficients.  The entries in the table are strings.

  t: Table(Polynomial Integer, String) := table()
    table()
                               Type: Table(Polynomial Integer,String)

To save an entry in the table, the setelt operation is used.  This can
be called directly, giving the table a key and an entry.

  setelt(t, x**2 - 1, "Easy to factor")
    "Easy to factor"
                               Type: String

Alternatively, you can use assignment syntax.

  t(x**3 + 1) := "Harder to factor"
    "Harder to factor"
                               Type: String

  t(x) := "The easiest to factor"
    "The easiest to factor"
                               Type: String

Entries are retrieved from the table by calling the elt operation.

  elt(t, x)
    "The easiest to factor"
                               Type: String

This operation is called when a table is "applied" to a key using this
or the following syntax.

  t.x
    "The easiest to factor"
                               Type: String

  t x
    "The easiest to factor"
                               Type: String

Parentheses are used only for grouping.  They are needed if the key is
an infixed expression.

  t.(x**2 - 1)
    "Easy to factor"
                               Type: String

Note that the elt operation is used only when the key is known to be
in the table, otherwise an error is generated.

  t (x**3 + 1)
    "Harder to factor"
                               Type: String

You can get a list of all the keys to a table using the keys operation.

  keys t
        3      2
    [x,x  + 1,x  - 1]
                               Type: List Polynomial Integer

If you wish to test whether a key is in a table, the search operation
is used.  This operation returns either an entry or "failed".

  search(x, t)
    "The easiest to factor"
                               Type: Union(String,...)

  search(x**2, t)
    "failed"
                               Type: Union("failed",...)

The return type is a union so the success of the search can be tested
using case.  

  search(x**2, t) case "failed"
    true
                               Type: Boolean

The remove operation is used to delete values from a table.

  remove!(x**2-1, t)
    "Easy to factor"
                               Type: Union(String,...)

If an entry exists under the key, then it is returned.  Otherwise
remove returns "failed".

  remove!(x-1, t)
    "failed"
                               Type: Union("failed",...)

The number of key-entry pairs can be found using the # operation.

  #t
    2
                               Type: PositiveInteger

Just as keys returns a list of keys to the table, a list of all the
entries can be obtained using the members operation.

  members t
   (17)  ["The easiest to factor","Harder to factor"]
                               Type: List String

A number of useful operations take functions and map them on to the
table to compute the result.  Here we count the entries which have
"Hard" as a prefix.

  count(s: String +-> prefix?("Hard", s), t)
    1
                               Type: PositiveInteger

Other table types are provided to support various needs.
  o AssociationList gives a list with a table view. This allows new 
    entries to be appended onto the front of the list to cover up old 
    entries. This is useful when table entries need to be stacked or when
    frequent list traversals are required.
  o EqTable gives tables in which keys are considered equal only when 
    they are in fact the same instance of a structure.
  o StringTable should be used when the keys are known to be strings.
  o SparseTable provides tables with default entries, so lookup never fails.
    The GeneralSparseTable constructor can be used to make any table type 
    behave this way.
  o KeyedAccessFile allows values to be saved in a file, accessed as a table.

See Also:
o )help AssociationList
o )help EqTable
o )help StringTable
o )help SparseTable
o )help GeneralSparseTable
o )help KeyedAccessFile
o )show Table

