NewSliceTable returns a new Table with data from the given slice of structs.
(st any)
| 14 | // NewSliceTable returns a new Table with data from the given slice |
| 15 | // of structs. |
| 16 | func NewSliceTable(st any) (*Table, error) { |
| 17 | npv := reflectx.NonPointerValue(reflect.ValueOf(st)) |
| 18 | if npv.Kind() != reflect.Slice { |
| 19 | return nil, fmt.Errorf("NewSliceTable: not a slice") |
| 20 | } |
| 21 | eltyp := reflectx.NonPointerType(npv.Type().Elem()) |
| 22 | if eltyp.Kind() != reflect.Struct { |
| 23 | return nil, fmt.Errorf("NewSliceTable: element type is not a struct") |
| 24 | } |
| 25 | dt := NewTable() |
| 26 | |
| 27 | for i := 0; i < eltyp.NumField(); i++ { |
| 28 | f := eltyp.Field(i) |
| 29 | switch f.Type.Kind() { |
| 30 | case reflect.Float32: |
| 31 | dt.AddFloat32Column(f.Name) |
| 32 | case reflect.Float64: |
| 33 | dt.AddFloat64Column(f.Name) |
| 34 | case reflect.String: |
| 35 | dt.AddStringColumn(f.Name) |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | nr := npv.Len() |
| 40 | dt.SetNumRows(nr) |
| 41 | for ri := 0; ri < nr; ri++ { |
| 42 | for i := 0; i < eltyp.NumField(); i++ { |
| 43 | f := eltyp.Field(i) |
| 44 | switch f.Type.Kind() { |
| 45 | case reflect.Float32: |
| 46 | dt.SetFloat(f.Name, ri, float64(npv.Index(ri).Field(i).Interface().(float32))) |
| 47 | case reflect.Float64: |
| 48 | dt.SetFloat(f.Name, ri, float64(npv.Index(ri).Field(i).Interface().(float64))) |
| 49 | case reflect.String: |
| 50 | dt.SetString(f.Name, ri, npv.Index(ri).Field(i).Interface().(string)) |
| 51 | } |
| 52 | } |
| 53 | } |
| 54 | return dt, nil |
| 55 | } |
| 56 | |
| 57 | // UpdateSliceTable updates given Table with data from the given slice |
| 58 | // of structs, which must be the same type as used to configure the table |