rows.go

  1package table
  2
  3// Data is the interface that wraps the basic methods of a table model.
  4type Data interface {
  5	// At returns the contents of the cell at the given index.
  6	At(row, cell int) string
  7
  8	// Rows returns the number of rows in the table.
  9	Rows() int
 10
 11	// Columns returns the number of columns in the table.
 12	Columns() int
 13}
 14
 15// StringData is a string-based implementation of the Data interface.
 16type StringData struct {
 17	rows    [][]string
 18	columns int
 19}
 20
 21// NewStringData creates a new StringData with the given number of columns.
 22func NewStringData(rows ...[]string) *StringData {
 23	m := StringData{columns: 0}
 24
 25	for _, row := range rows {
 26		m.columns = max(m.columns, len(row))
 27		m.rows = append(m.rows, row)
 28	}
 29
 30	return &m
 31}
 32
 33// Append appends the given row to the table.
 34func (m *StringData) Append(row []string) {
 35	m.columns = max(m.columns, len(row))
 36	m.rows = append(m.rows, row)
 37}
 38
 39// At returns the contents of the cell at the given index.
 40func (m *StringData) At(row, cell int) string {
 41	if row >= len(m.rows) || cell >= len(m.rows[row]) {
 42		return ""
 43	}
 44
 45	return m.rows[row][cell]
 46}
 47
 48// Columns returns the number of columns in the table.
 49func (m *StringData) Columns() int {
 50	return m.columns
 51}
 52
 53// Item appends the given row to the table.
 54func (m *StringData) Item(rows ...string) *StringData {
 55	m.columns = max(m.columns, len(rows))
 56	m.rows = append(m.rows, rows)
 57	return m
 58}
 59
 60// Rows returns the number of rows in the table.
 61func (m *StringData) Rows() int {
 62	return len(m.rows)
 63}
 64
 65// Filter applies a filter on some data.
 66type Filter struct {
 67	data   Data
 68	filter func(row int) bool
 69}
 70
 71// NewFilter initializes a new Filter.
 72func NewFilter(data Data) *Filter {
 73	return &Filter{data: data}
 74}
 75
 76// Filter applies the given filter function to the data.
 77func (m *Filter) Filter(f func(row int) bool) *Filter {
 78	m.filter = f
 79	return m
 80}
 81
 82// At returns the row at the given index.
 83func (m *Filter) At(row, cell int) string {
 84	j := 0
 85	for i := range m.data.Rows() {
 86		if m.filter(i) {
 87			if j == row {
 88				return m.data.At(i, cell)
 89			}
 90
 91			j++
 92		}
 93	}
 94
 95	return ""
 96}
 97
 98// Columns returns the number of columns in the table.
 99func (m *Filter) Columns() int {
100	return m.data.Columns()
101}
102
103// Rows returns the number of rows in the table.
104func (m *Filter) Rows() int {
105	j := 0
106	for i := range m.data.Rows() {
107		if m.filter(i) {
108			j++
109		}
110	}
111
112	return j
113}
114
115// DataToMatrix is a helper function that converts an object that implements the
116// Data interface into a table.
117func DataToMatrix(data Data) (rows [][]string) {
118	numRows := data.Rows()
119	numCols := data.Columns()
120	rows = make([][]string, numRows)
121
122	for i := range numRows {
123		rows[i] = make([]string, numCols)
124
125		for j := range numCols {
126			rows[i][j] = data.At(i, j)
127		}
128	}
129	return
130}