Json 如何使用golang将活动字段更改为非活动字段并保持字段值不变?

Json 如何使用golang将活动字段更改为非活动字段并保持字段值不变?,json,go,Json,Go,我对图像有以下json结构: {"image": [ { "bytesize": "-2", "default": "redlight_drdefault" }, { "active": "JV77tdMcHkChFaF2H9uoDHepPhUcrlprYEsQr-r-1lg=", "bytesize": "566806" } ]} 我想将名为“active”的字段更改为“inactive”,而不更改字段中存储的值,如下所示: {"im

我对图像有以下json结构:

 {"image": [
  {
    "bytesize": "-2",
    "default": "redlight_drdefault"
  },
  {
    "active": "JV77tdMcHkChFaF2H9uoDHepPhUcrlprYEsQr-r-1lg=",
    "bytesize": "566806"
  }
]}
我想将名为“active”的字段更改为“inactive”,而不更改字段中存储的值,如下所示:

    {"image": [
  {
    "bytesize": "-2",
    "default": "redlight_drdefault"
  },
  {
    "inactive": "JV77tdMcHkChFaF2H9uoDHepPhUcrlprYEsQr-r-1lg=",
    "bytesize": "566806"
  }
]}
var a Active
// decode JSON into a
var b Inactive = Inactive(a) // direct conversion allowed
有人有解决办法吗?如果你能在操场上展示这一点,那就太好了

我很难添加新值,即:

    mapactive := map[string]string{"active": "gj65vn768=", 
    "bytesize":"76878768" }

如何将其附加到提供给我的解决方案中???这应该附加在使所有活动键处于非活动状态的末尾。

Golang允许在类型相同的结构之间直接转换,即使它们在字段标记上不同。也就是说,您可以直接在以下两者之间进行转换:

type Active struct {
    Active   string `json:"active"`
    ByteSize string `json:"bytesize"`
}

使用以下命令:

    {"image": [
  {
    "bytesize": "-2",
    "default": "redlight_drdefault"
  },
  {
    "inactive": "JV77tdMcHkChFaF2H9uoDHepPhUcrlprYEsQr-r-1lg=",
    "bytesize": "566806"
  }
]}
var a Active
// decode JSON into a
var b Inactive = Inactive(a) // direct conversion allowed
但是,您的输入JSON不容易支持这一点。您的输入JSON将
image
字段列为一个列表,尽管列表中的各种条目在类型或字段上并不完全相同。在这种情况下,唯一的实际选择是将其解析为一组嵌套的
map[string]接口{}

请注意,我已经从这段代码中删除了许多健全性检查,以使其更简短、更具可读性。使用嵌套接口映射来处理JSON本质上是混乱的。如果您可以更改输入JSON的格式,那么您的运气会更好,代码也更容易维护

package main

import (
    "fmt"
    "encoding/json"
)

func main() {
    fmt.Println("Hello, playground")

    var x S

    json.Unmarshal(data,&x)
    for _,img:=range x.Image {
        Deactive(img)
    }


    b,_:=json.Marshal(x)
    fmt.Println(string(b))
}

type S struct {
    Image []map[string]interface{} `json:"image"`
}

func Deactive(x map[string]interface{}) {
    if v,ok := x["active"]; ok {
        delete(x,"active")
        x["inactvie"]=v
    }
}

var data = []byte(` {"image": [
  {
    "bytesize": "-2",
    "default": "redlight_drdefault"
  },
  {
    "active": "JV77tdMcHkChFaF2H9uoDHepPhUcrlprYEsQr-r-1lg=",
    "bytesize": "566806"
  }
]}
`)
正如我所说,使用
map[string]接口{}
。但是把它尽可能深地放在嵌套结构中,因为它是混乱和棘手的


Deactive
在地图中查找一个
active
键,如果有,它将获取该值,插入一个带有该值的
inactive
键,并删除带有预定义结构的
actvie
解决方案


使用
map[string]interface{}
我已经尝试过了,但无法做到这一点。我认为第一种类型不能相互转换。你能提供一个游乐场链接吗?这是:
不能将(活动类型)转换为非活动类型
。我认为你混淆了结构和接口?废话,对不起,你是对的,它们必须有相同的字段名。更新答案,现在编译:谢谢@Kaedys的帮助。我已经解决了所有问题。
package main

import (
    "encoding/json"
    "fmt"
)

type (
    images struct {
        Image []image `json:"image"`
    }

    image struct {
        Active string `json:"active,omitempty"`
        common
    }

    newImages struct {
        Image []newImage `json:"image"`
    }

    newImage struct {
        common
        Inactive string `json:"inactive,omitempty"`
    }

    common struct {
        Bytesize string `json:"bytesize"`
        Default  string `json:"default,omitempty"`
    }
)

var i = []byte(`
 {"image": [
  {
    "bytesize": "-2",
    "default": "redlight_drdefault"
  },
  {
    "active": "JV77tdMcHkChFaF2H9uoDHepPhUcrlprYEsQr-r-1lg=",
    "bytesize": "566806"
  }
]}
`)

func main() {

    var images images
    e := json.Unmarshal(i, &images)
    if e != nil {
        panic(e)
    }

    var newImages newImages
    for k, _ := range images.Image {

        newImg := newImage{}
        if len(images.Image[k].Active) > 0 {
            newImg.Inactive = images.Image[k].Active
        }
        newImg.Default = images.Image[k].Default
        newImg.Bytesize = images.Image[k].Bytesize
        newImages.Image = append(newImages.Image, newImg)

    }

    result, e := json.Marshal(newImages)
    if e != nil {
        panic(e)
    }
    fmt.Println(string(result))
}