Documentation ¶
Overview ¶
Package table implements ordered, grouped two dimensional relations.
There are two related abstractions: Table and Grouping.
A Table is an ordered relation of rows and columns. Each column is a Go slice and hence must be homogeneously typed, but different columns may have different types. All columns in a Table have the same number of rows.
A Grouping generalizes a Table by grouping the Table's rows into zero or more groups. A Table is itself a Grouping with zero or one groups. Most operations take a Grouping and operate on each group independently, though some operations sub-divide or combine groups.
The structures of both Tables and Groupings are immutable. They are constructed using a Builder or a GroupingBuilder, respectively, and then "frozen" into their respective immutable data structures.
Index ¶
- Variables
- func ColType(g Grouping, col string) reflect.Type
- func Fprint(w io.Writer, g Grouping, formats ...string) error
- func MapCols(g Grouping, f interface{}, incols ...string) func(outcols ...string) Grouping
- func Print(g Grouping, formats ...string) error
- type Builder
- type GroupID
- type Grouping
- func Concat(gs ...Grouping) Grouping
- func Filter(g Grouping, pred interface{}, cols ...string) Grouping
- func FilterEq(g Grouping, col string, val interface{}) Grouping
- func GroupBy(g Grouping, cols ...string) Grouping
- func Head(g Grouping, n int) Grouping
- func HeadTables(g Grouping, n int) Grouping
- func Join(g1 Grouping, col1 string, g2 Grouping, col2 string) Grouping
- func MapTables(g Grouping, f func(gid GroupID, table *Table) *Table) Grouping
- func Pivot(g Grouping, label, value string) Grouping
- func Remove(g Grouping, col string) Grouping
- func Rename(g Grouping, from, to string) Grouping
- func SortBy(g Grouping, cols ...string) Grouping
- func Tail(g Grouping, n int) Grouping
- func TailTables(g Grouping, n int) Grouping
- func Ungroup(g Grouping) Grouping
- func Unpivot(g Grouping, label, value string, cols ...string) Grouping
- type GroupingBuilder
- type Slice
- type Table
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var RootGroupID = GroupID{}
RootGroupID is the root of the GroupID tree.
Functions ¶
func ColType ¶
ColType returns the type of column col in g. This will always be a slice type, even if col is a constant column. ColType panics if col is unknown.
TODO: If I introduce a first-class representation for a grouped column, this should probably be in that.
func Fprint ¶
Fprint prints Grouping g to w. formats[i] specifies a fmt-style format string for column i. If there are more columns than formats, remaining columns are formatted with %v (in particular, formats may be omitted entirely to use %v for all columns). Numeric columns are right aligned; all other column types are left aligned.
Example ¶
tab := new(Builder). Add("name", []string{"Washington", "Adams", "Jefferson"}). Add("terms", []int{2, 1, 2}). Done() Fprint(os.Stdout, tab)
Output: name terms Washington 2 Adams 1 Jefferson 2
func MapCols ¶
MapCols applies f to a set of input columns to construct a set of new output columns.
For each Table in g, MapCols calls f(in[0], in[1], ..., out[0], out[1], ...) where in[i] is column incols[i]. f should process the values in the input column slices and fill output columns slices out[j] accordingly. MapCols returns a new Grouping that adds each outcols[j] bound to out[j].
If all of the input columns are constant for a given table, MapCols will call f with all slices of length 1. The input column slices will contain the constant column values and MapCols will bind each output column value out[i][0] as a constant.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
A Builder constructs a Table one column at a time.
The zero value of a Builder represents an empty Table.
func NewBuilder ¶
NewBuilder returns a new Builder. If t is non-nil, it populates the new Builder with the columns from t.
func (*Builder) Add ¶
Add adds a column to b, or removes the named column if data is nil. If b already has a column with the given name, Add replaces it. If data is non-nil, it must have the same length as any existing columns or Add will panic.
func (*Builder) AddConst ¶
AddConst adds a constant column to b whose value is val. If b already has a column with this name, AddConst replaces it.
A constant column has the same value in every row of the Table. It does not itself have an inherent length.
type GroupID ¶
type GroupID struct {
// contains filtered or unexported fields
}
GroupID identifies a group. GroupIDs form a tree, rooted at RootGroupID (which is also the zero GroupID).
func (GroupID) Extend ¶
Extend returns a new GroupID that is a child of GroupID g. The returned GroupID will not be equal to any existing GroupID (even if label is not unique among g's children). The label is primarily diagnostic; the table package uses it only when printing tables, but callers may store semantic information in group labels.
type Grouping ¶
type Grouping interface { // Columns returns the names of the columns in this Grouping, // or nil if there are no Tables or the group consists solely // of empty Tables. All Tables in this Grouping have the same // set of columns. Columns() []string // Tables returns the group IDs of the tables in this // Grouping. Tables() []GroupID // Table returns the Table in group gid, or nil if there is no // such Table. Table(gid GroupID) *Table }
A Grouping is an immutable set of tables with identical sets of columns, each identified by a distinct GroupID.
Visually, a Grouping can be thought of as follows:
Col A Col B Col C ------ group /a ------ 0 5.4 "x" 90 1 -.2 "y" 30 ------ group /b ------ 0 9.3 "a" 10
Like a Table, a Grouping's structure is immutable. To construct a Grouping, use a GroupingBuilder.
Despite the fact that GroupIDs form a hierarchy, a Grouping ignores this hierarchy and simply operates on a flat map of distinct GroupIDs to Tables.
func Concat ¶
Concat returns the concatenation of the rows in each matching group across gs. All Groupings in gs must have the same set of columns (though they need not be in the same order; the column order from gs[0] will be used). The GroupIDs in the returned Grouping will be the union of the GroupIDs in gs.
func Filter ¶
Filter filters g to only rows where pred returns true. pred must be a function that returns bool and takes len(cols) arguments where the type of col[i] is assignable to argument i.
TODO: Create a faster batch variant where pred takes slices.
func GroupBy ¶
GroupBy sub-divides all groups such that all of the rows in each group have equal values for all of the named columns. The relative order of rows with equal values for the named columns is maintained. Grouped-by columns become constant columns within each group.
func HeadTables ¶
HeadTables returns the first n tables in g.
func Join ¶
Join joins g1 and g2 on tables with identical group IDs where col1 in g1 equals col2 in g2. It maintains the group order of g1, except that groups that aren't in g2 are removed, and maintains the row order of g1, followed by the row order of g2.
TODO: Support join on more than one column.
func MapTables ¶
MapTables applies f to each Table in g and returns a new Grouping with the same group structure as g, but with the Tables returned by f.
func Pivot ¶
Pivot converts rows of g into columns. label and value must name columns in g, and the label column must have type []string. Pivot returns a Grouping with a new column named after each distinct value in the label column, where the values in that column correspond to the values from the value column. All other columns (besides label and value) are copied to the output. If, for a given column in an output row, no input row has that column in the label column, the output cell will have the zero value for its type.
Example ¶
fmt.Println("Original table") Print(stateTempByKind) fmt.Println() fmt.Println("Pivoted table") Print(Pivot(stateTempByKind, "kind", "temperature"))
Output: Original table state kind temperature Alabama high 122 Alabama low -27 Alaska high 100 Alaska low -80 Pivoted table state high low Alabama 122 -27 Alaska 100 -80
func SortBy ¶
SortBy sorts each group of g by the named columns. If a column's type implements sort.Interface, rows will be sorted according to that order. Otherwise, the values in the column must be naturally ordered (their types must be orderable by the Go specification). If neither is true, SortBy panics with a *generic.TypeError. If more than one column is given, SortBy sorts by the tuple of the columns; that is, if two values in the first column are equal, they are sorted by the second column, and so on.
func TailTables ¶
TailTables returns the first n tables in g.
func Ungroup ¶
Ungroup concatenates adjacent Tables in g that share a group parent into a Table identified by the parent, undoing the effects of the most recent GroupBy operation.
func Unpivot ¶
Unpivot converts columns of g into rows. The returned Grouping consists of the columns of g *not* listed in cols, plus two columns named by the label and value arguments. For each input row in g, the returned Grouping will have len(cols) output rows. The i'th such output row corresponds to column cols[i] in the input row. The label column will contain the name of the unpivoted column, cols[i], and the value column will contain that column's value from the input row. The values of all other columns in the input row will be repeated across the output rows. All columns in cols must have the same type.
Example ¶
fmt.Println("Original table") Print(stateTemp) fmt.Println() fmt.Println("Unpivoted table") Print(Unpivot(stateTemp, "kind", "temperature", "high", "low"))
Output: Original table state high low Alabama 122 -27 Alaska 100 -80 Unpivoted table state kind temperature Alabama high 122 Alabama low -27 Alaska high 100 Alaska low -80
type GroupingBuilder ¶
type GroupingBuilder struct {
// contains filtered or unexported fields
}
A GroupingBuilder constructs a Grouping one table a time.
The zero value of a GroupingBuilder represents an empty Grouping with no tables and no columns.
func NewGroupingBuilder ¶
func NewGroupingBuilder(g Grouping) *GroupingBuilder
NewGroupingBuilder returns a new GroupingBuilder. If g is non-nil, it populates the new GroupingBuilder with the tables from g.
func (*GroupingBuilder) Add ¶
func (b *GroupingBuilder) Add(gid GroupID, t *Table) *GroupingBuilder
Add adds a Table to b, or removes a table if t is nil. If t is the empty Table, this is a no-op because the empty Table contains no groups. If gid already exists, Add replaces it. Table t must have the same columns as any existing Tables in this Grouping and they must have identical types; otherwise, Add will panic.
TODO This doesn't make it easy to combine two Groupings. It could instead take a Grouping and reparent it.
func (*GroupingBuilder) Done ¶
func (b *GroupingBuilder) Done() Grouping
Done returns the constructed Grouping and resets b.
type Slice ¶
type Slice interface{}
A Slice is a Go slice value.
This is primarily for documentation. There is no way to statically enforce this in Go; however, functions that expect a Slice will panic with a *generic.TypeError if passed a non-slice value.
type Table ¶
type Table struct {
// contains filtered or unexported fields
}
A Table is an immutable, ordered two dimensional relation. It consists of a set of named columns. Each column is a sequence of values of a consistent type or a constant value. All (non-constant) columns have the same length.
The zero value of Table is the "empty table": it has no rows and no columns. Note that a Table may have one or more columns, but no rows; such a Table is *not* considered empty.
A Table is also a trivial Grouping. If a Table is empty, it has no groups and hence the zero value of Table is also the "empty group". Otherwise, it consists only of the root group, RootGroupID.
func Flatten ¶
Flatten concatenates all of the groups in g into a single Table. This is equivalent to repeatedly Ungrouping g.
func TableFromStrings ¶
TableFromStrings converts a [][]string to a Table. This is intended for processing external data, such as from CSV files. If coerce is true, TableFromStrings will convert columns to []int or []float when every string in that column is accepted by strconv.ParseInt or strconv.ParseFloat, respectively.
Example ¶
const csvData = `name,terms Washington,2 Adams,1 Jefferson,2` rows, _ := csv.NewReader(bytes.NewBufferString(csvData)).ReadAll() Print(TableFromStrings(rows[0], rows[1:], true))
Output: name terms Washington 2 Adams 1 Jefferson 2
func TableFromStructs ¶
TableFromStructs converts a []T where T is a struct to a Table where the columns of the table correspond to T's exported fields.
Example ¶
type prez struct { Name string Terms int } data := []prez{{"Washington", 2}, {"Adams", 1}, {"Jefferson", 2}} Print(TableFromStructs(data))
Output: Name Terms Washington 2 Adams 1 Jefferson 2
func (*Table) Column ¶
Column returns the slice of data in column name of Table t, or nil if there is no such column. If name is a constant column, this returns a slice with the constant value repeated to the length of the Table.
func (*Table) Columns ¶
Columns returns the names of the columns in Table t, or nil if this Table is empty.
func (*Table) Const ¶
Const returns the value of constant column name. If this column does not exist or is not a constant column, Const returns nil, false.
func (*Table) MustColumn ¶
MustColumn is like Column, but panics if there is no such column.