Skip to content

Instantly share code, notes, and snippets.

@joesonw
Created April 19, 2019 06:00
Show Gist options
  • Select an option

  • Save joesonw/c4c95494d876090469236c34cc71ac1d to your computer and use it in GitHub Desktop.

Select an option

Save joesonw/c4c95494d876090469236c34cc71ac1d to your computer and use it in GitHub Desktop.

Revisions

  1. joesonw created this gist Apr 19, 2019.
    101 changes: 101 additions & 0 deletions stringarray.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@

    import (
    "encoding/json"
    "strings"
    )

    type String struct {
    isArray bool
    stringVal string
    arrayVal []string
    }

    func (a *String) UnmarshalJSON(data []byte) error {
    if data[0] == '[' {
    a.isArray = true
    return json.Unmarshal(data, &a.arrayVal)
    }
    return json.Unmarshal(data, &a.stringVal)
    }

    func (a *String) MarshalJSON() ([]byte, error) {
    if a.isArray {
    return json.Marshal(&a.arrayVal)
    }
    return json.Marshal(&a.stringVal)
    }

    func (a String) IsArray() bool {
    return a.isArray
    }

    func (a String) ToArray() []string {
    return a.arrayVal[:]
    }

    func (a String) ToString() string {
    return a.stringVal
    }

    func (a String) MustToArray() []string {
    if !a.isArray {
    return []string{a.ToString()}
    }
    return a.ToArray()
    }

    func (a String) Length() int {
    if a.isArray {
    return len(a.arrayVal)
    }
    return 1
    }

    func (a String) String() string {
    if a.isArray {
    return strings.Join(a.arrayVal, ",")
    }
    return a.stringVal
    }

    func (a String) Clone() *String {
    newA := &String{isArray: a.isArray}
    if a.isArray {
    newA.arrayVal = make([]string, len(a.arrayVal))
    copy(newA.arrayVal, a.arrayVal)
    } else {
    newA.stringVal = a.stringVal
    }
    return newA
    }

    func (a String) Foreach(fn func(s string)) {
    array := a.MustToArray()
    for _, s := range array {
    fn(s)
    }
    }

    func (a String) Map(fn func(s string) string) *String {
    if a.IsArray() {
    array := make([]string, len(a.arrayVal))
    for i, s := range a.arrayVal {
    array[i] = fn(s)
    }
    return NewString(array...)
    } else {
    return NewString(fn(a.stringVal))
    }
    }

    func (a String) Join(delimiter string) string {
    return strings.Join(a.MustToArray(), delimiter)
    }

    func NewString(str ...string) *String {
    if len(str) > 1 {
    a := &String{isArray: true, arrayVal: str}
    return a
    }
    return &String{stringVal: str[0]}
    }