修改JSON对象数组

huangapple go评论101阅读模式
英文:

Modifying JSON array of objects

问题

我正在尝试使用tidwall/sjson来修改JSON对象中的属性,但是遇到了以下错误:

./prog.go:34:77: 语法错误: 意外的 {期望表达式

以下是我的代码:

package main

import (
	"fmt"
	"github.com/tidwall/sjson"
)

func main() {
	config := `{
                 "root": {
                   "obj1Arr": [
         	         {
		               "obj2": {
		                 "obj3Arr": [
		                   {
                		     "key1": "val1",
		                     "key2": {
                		       "val2": ["a", "b"]
                  		     }
	                       },
		              	   {
		                     "key3": "val3",
                		     "key4": "val4"
                		   }
              		     ]
		               }
        		     }
      		       ]
		         },
		         "strExample": "bar",
		         "boolExample": true,
		         "floatExample": 12.54
		       }`
	value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}[{"hello":"world"}])
	fmt.Println(value)
}

你可以使用这个Go Playground链接重现这个错误。我试图修改对象root.obj1Arr[0].obj2.obj3Arr,使其只包含一个对象。我还尝试使用非结构化对象进行操作。如何修复这个错误?

英文:

I'm trying to use tidwall/sjson to modify properties in a json object, but getting the following error:

./prog.go:34:77: syntax error: unexpected {, expecting expression

Here's my code:

package main

import (
	"fmt"
	"github.com/tidwall/sjson"
)

func main() {
	config := `{
                 "root": {
                   "obj1Arr": [
         	         {
		               "obj2": {
		                 "obj3Arr": [
		                   {
                		     "key1": "val1",
		                     "key2": {
                		       "val2": ["a", "b"]
                  		     }
	                       },
		              	   {
		                     "key3": "val3",
                		     "key4": "val4"
                		   }
              		     ]
		               }
        		     }
      		       ]
		         },
		         "strExample": "bar",
		         "boolExample": true,
		         "floatExample": 12.54
		       }`
	value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}[{"hello":"world"}])
	fmt.Println(value)
}

You can reproduce the error with this go playground link. I'm trying to modify the object root.obj1Arr[0].obj2.obj3Arr to simply have a single object inside of it. I'm also trying to work with an unstructured object. How can I fix this error?

答案1

得分: 2

一个切片的复合字面量使用{}而不是[]来创建,例如:

value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{map[string]string{"hello":"world"}})

https://play.golang.org/p/1h07L5KNVTR

请注意,你不能使用复合字面量语法创建匿名对象。在示例中,我选择使用了map[string]string。如果你的类型不是那么简单,或者根本不知道类型,你可以使用map[string]interface{},例如map[string]interface{}{"my": map[string]interface{}{"nested": []string{"values", "are", "here"}}}

英文:

A slice composite literal is created using {} instead of [] e.g.

value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{map[string]string{"hello":"world"}})

https://play.golang.org/p/1h07L5KNVTR

Note that you cannot create an anonymous object using composite literal syntax. I chose to use a map[string]string in the example. If your types aren't that simple, or simply aren't known, you can use map[string]interface{} e.g. map[string]interface{}{"my": map[string]interface{}{"nested": []string{"values", "are", "here"}}}

答案2

得分: 1

你的[]interface{}[{"hello":"world"}]不是有效的Go表达式,因为:

  1. 切片字面量应该使用[]type{...}而不是[]type[...]
  2. 你用来初始化切片中的映射(在JSON中表示对象数组)的字面量不合法,因为它缺少前面的类型,应该是:map[string]string{"hello": "world"}

所以,要将obj3Arr修改为map[string]string类型的数组,代码应该是这样的:

value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []map[string]string{map[string]string{"hello":"world"}})

如果你要处理在编译时不知道结构和类型的对象(根据你问题中的“我也在尝试处理一个非结构化对象”),你需要在映射中使用空的interface{}作为类型,而不是stringmap[string]interface{}。这样你就可以在映射值中存储各种类型:

value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{
map[string]interface{}{
	"hello": "world", 
	"key2": true, 
	"listkey": []int{1,2,3,4}, 
	"mapkey": map[int][]bool{1: []bool{true, true, false}}},
})

将会生成:

"obj3Arr": [{"hello":"world","key2":true,"listkey":[1,2,3,4],"mapkey":{"1":[true,true,false]}}]
英文:

Your []interface{}[{"hello":"world"}] is not valid Go expression as

  1. Slice literal is initialized with []type{...} and not []type[...]
  2. Literal you use to initialize a map inside slice (what you want in object array in JSON) is not valid as it lacks type in front of it, should be: map[string]string{"hello": "world"}

So to modify obj3Arr to be an array of map[string]string the code should be something like:

value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []map[string]string{map[string]string{"hello":"world"}})

To work with objects where you don't know structure and types at compile time (as per "I'm also trying to work with an unstructured object" in your question) you will need empty interface{} as type in map instead of string: map[string]interface{}. So that you can store various types in that map values:

value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{
map[string]interface{}{
	"hello": "world", 
	"key2": true, 
	"listkey": []int{1,2,3,4}, 
	"mapkey": map[int][]bool{1: []bool{true, true, false}}},
})

will produce:

"obj3Arr": [{"hello":"world","key2":true,"listkey":[1,2,3,4],"mapkey":{"1":[true,true,false]}}]

答案3

得分: 1

根据建议,将[]interface{}[{"hello":"world"}]替换为[]interface{}{map[string]string{"hello": "world"}}

package main

import (
	"fmt"
	"github.com/tidwall/sjson"
)

func main() {
	config := `{
                        "root": {
                          "obj1Arr": [
             	        {
    		          "obj2": {
    		              "obj3Arr": [
    		                {
                    		  "key1": "val1",
    		                  "key2": {
                    		    "val2": ["a", "b"]
                      		  }
    	                        },
    		              	{
    		                  "key3": "val3",
                    		  "key4": "val4"
                    		}
                  		       ]
    		          }
            		}
          		      ]
    		    },
    		    "strExample": "bar",
    		    "boolExample": true,
    		    "floatExample": 12.54
    		  }`
	value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{map[string]string{"hello": "world"}})
	fmt.Println(value)

}

输出结果:

{
  "root": {
    "obj1Arr": [
      {
        "obj2": {
          "obj3Arr": [{"hello":"world"}]
        }
      }
    ]
  },
  "strExample": "bar",
  "boolExample": true,
  "floatExample": 12.54
}
英文:

Based on the suggestions changing replacing []interface{}[{"hello":"world"}] with []interface{}{map[string]string{"hello": "world"}}

package main

import (
	"fmt"
	"github.com/tidwall/sjson"
)

func main() {
	config := `{
                    "root": {
                      "obj1Arr": [
         	        {
		          "obj2": {
		              "obj3Arr": [
		                {
                		  "key1": "val1",
		                  "key2": {
                		    "val2": ["a", "b"]
                  		  }
	                        },
		              	{
		                  "key3": "val3",
                		  "key4": "val4"
                		}
              		       ]
		          }
        		}
      		      ]
		    },
		    "strExample": "bar",
		    "boolExample": true,
		    "floatExample": 12.54
		  }`
	value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{map[string]string{"hello": "world"}})
	fmt.Println(value)

}

Output:

{
                    "root": {
                      "obj1Arr": [
                        {
                          "obj2": {
                              "obj3Arr": [{"hello":"world"}]
                          }
                        }
                      ]
                    },
                    "strExample": "bar",
                    "boolExample": true,
                    "floatExample": 12.54
                  }

huangapple
  • 本文由 发表于 2021年7月30日 06:45:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/68583575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定