在 Go 中将对象转换为对象数组 (JSON)

Convert an object to an array of objects (JSON) in Go

我正在将 JS API 转换为 Go。我使用来自第三方的数据,其中有时 属性 是各种键、值的对象而不是对象数组(键、值)。

所以在我的前端,如果它是一个对象,它不会呈现,所以我将它转换成一个对象数组。

我目前在 JS 中这样做:

if (!Array.isArray(data.attributes)) {
      // convert into array of objects; only works for non separate key:key value:value
      data.attributes = Object.entries(data.attributes).map(
        ([key, value]) => ({
          type: key,
          value: value,
        })
      );
    }

data 是 JSON 响应中的 属性,例如: {... data: { "attributes": [{...}{...}]}

所以偶尔属性会是 {... data: { "attributes": {name: "John", age: "20" }:

我如何在 Go 中做这样的事情?谢谢。

使用声明的类型,您可以实现 json.Unmarshaler 接口来自定义 JSON 的解组方式。

在实现中,您可以通过简单地查看第一个和最后一个字节以查看其 {-and-[= 来检查 JSON 数据是否表示对象或数组13=] 或 [-和-]。根据该检查,您可以决定如何进一步进行,这是一个示例:

type Attr struct {
    Type  string
    Value interface{}
}

type AttrList []Attr

func (ls *AttrList) UnmarshalJSON(data []byte) error {
    if len(data) == 0 { // nothing to do
        return nil
    }

    switch last := len(data)-1; {
    // is array?
    case data[0] == '[' && data[last] == ']':
        return json.Unmarshal(data, (*[]Attr)(ls))

    // is object?
    case data[0] == '{' && data[last] == '}':
        var obj map[string]interface{}
        if err := json.Unmarshal(data, &obj); err != nil {
            return err
        }
        for key, value := range obj {
            *ls = append(*ls, Attr{Type: key, Value: value})
        }
        return nil
    }

    return errors.New("unsupported JSON type for AttrList")
}

https://go.dev/play/p/X5LV8G87bLJ