遍历 JSON 以获取随机对象

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

Iterating over Json for random object

问题

我遇到了查询这个 JSON 的问题。

{
   "cars":{
      "dfhuidsfiusd":{
         "name":"Mercedes",
          "details": {
             "plate_number":"sas2-hd-3",
             "year": 2009
         }

      },
      "uiwouiouss":{
         "name":"Jaguar",
          "details": {
             "plate_number":"sas2-hd-3",
             "year": 2009
         }
      },
      "sdikdshkjsd":{
         "name":"Toyota",
          "details": {
             "plate_number":"sas2-hd-3",
             "year": 2009
         }
      }
   }
}

为了获取 details 对象中的元素,我需要通过这些可能会改变的随机值。

我决定使用这个库 https://github.com/tidwall/gjson
代码:

result := gjson.Get(json, `cars.#.details(year="2009")`)

println(result.String())

由于它们都具有相同的 year=2009 值,我期望得到以下输出:

dfhuidsfiusd
sdikdshkjsd
uiwouiouss

但它只打印出空值。

将这些随机值放入数组并进行迭代可能会起作用,但我希望假设这些值事先是未知的,谢谢。

英文:

I'm having issues querying over this json

{
   "cars":{
      "dfhuidsfiusd":{
         "name":"Mercedes",
          details: {
             "plate_number":"sas2-hd-3",
             "year": 2009
         }

      },
      "uiwouiouss":{
         "name":"Jaguar",
          details: {
             "plate_number":"sas2-hd-3",
             "year": 2009
         },
      },
      "sdikdshkjsd":{
         "name":"Toyota",
          details: {
             "plate_number":"sas2-hd-3",
             "year": 2009
         }
      }
   }
}

To get elements in the details object i need to pass through these random values which could change.

I decided to go with this library https://github.com/tidwall/gjson
code :

result := gjson.Get(json, `cars.#.details(year="2009")`)

println(result.String())

Since they all value year=2009 in common, I am expecting the following output:

dfhuidsfiusd
sdikdshkjsd
uiwouiouss

But it's just prints empty

Putting these random values in an array and iterating might work, but I want to assume these values are not known beforehand, thanks.

答案1

得分: 2

我认为只使用#*是无法获取项目名称的。您需要手动迭代这些项目:

gjson.Get(json, "cars").ForEach(func(path, value gjson.Result) bool {
    value.ForEach(func(method, value gjson.Result) bool {
        y := value.Get("year")
        if y.Int() == 2009 {
            fmt.Println(path)
        }
        return true
    })
    return true
})
英文:

I think it is not possible to get items' names by just using # or *. You have to iterate over those items manually:

gjson.Get(json, "cars").ForEach(func(path, value gjson.Result) bool {
	value.ForEach(func(method, value gjson.Result) bool {
		y := value.Get("year")
		if y.Int() == 2009 {
			fmt.Println(path)
		}
		return true
	})
	return true
})

答案2

得分: 2

我阅读了一些文档,希望这可以帮到你:

package main

import (
	"github.com/tidwall/gjson"
)

func main() {
	json := `{
		"cars":{
		   "dfhuidsfiusd":{
			  "name":"Mercedes",
			   "details": {
				  "plate_number":"sas2-hd-3",
				  "year": 2010
			  }

		   },
		   "uiwouiouss":{
			  "name":"Jaguar",
			   "details": {
				  "plate_number":"sas2-hd-3",
				  "year": 2010
			  },
		   },
		   "sdikdshkjsd":{
			  "name":"Toyota",
			   "details": {
				  "plate_number":"sas2-hd-3",
				  "year": 2012
			  }
		   }
		}
	}`

	result := gjson.Get(json, `cars.@values.#(details.year=2010)#.name`)

	println(result.String())
}
英文:

I read the documentation a bit, hope this helps:

package main

import (
	"github.com/tidwall/gjson"
)

func main() {
	json := `{
	"cars":{
	   "dfhuidsfiusd":{
		  "name":"Mercedes",
		   "details": {
			  "plate_number":"sas2-hd-3",
			  "year": 2010
		  }

	   },
	   "uiwouiouss":{
		  "name":"Jaguar",
		   "details": {
			  "plate_number":"sas2-hd-3",
			  "year": 2010
		  },
	   },
	   "sdikdshkjsd":{
		  "name":"Toyota",
		   "details": {
			  "plate_number":"sas2-hd-3",
			  "year": 2012
		  }
	   }
	}
 }`

	result := gjson.Get(json, `cars.@values.#(details.year=2010)#.name`)

	println(result.String())
}

答案3

得分: -1

你可以使用标准的encoding/json包,而不需要添加外部依赖。

将JSON解析为与JSON结构匹配的Go类型。Go映射对应于具有未知字段名称的JSON对象。遍历结果。

var v struct {
    Cars map[string]struct {
        Name    string
        Details struct {
            Plate_Number string
            Year         int
        }
    }
}
if err := json.Unmarshal(data, &v); err != nil {
    log.Fatal(err)
}
for k, car := range v.Cars {
    fmt.Println(k, car.Name, car.Details.Plate_Number, car.Details.Year)
}

该程序的输出为:

uiwouiouss Jaguar sas2-hd-3 2009
sdikdshkjsd Toyota sas2-hd-3 2009
dfhuidsfiusd Mercedes sas2-hd-3 2009

这里运行代码。

使用以下代码收集年份为2009的对象键:

var keys []string
for k, car := range v.Cars {
    if car.Details.Year == 2009 {
        keys = append(keys, k)
    }
}
英文:

You can use the standard encoding/json package instead of adding an external dependency.

Unmarshal the JSON to a Go type matching the structure of the JSON. A Go map corresponds to a JSON object with unknown field names. Iterate through the result.

var v struct {
	Cars map[string]struct {
		Name    string
		Details struct {
			Plate_Number string
			Year         int
		}
	}
}
if err := json.Unmarshal(data, &v); err != nil {
	log.Fatal(err)
}
for k, car := range v.Cars {
	fmt.Println(k, car.Name, car.Details.Plate_Number, car.Details.Year)
}

The output of this program is:

uiwouiouss Jaguar sas2-hd-3 2009
sdikdshkjsd Toyota sas2-hd-3 2009
dfhuidsfiusd Mercedes sas2-hd-3 2009

Run the code here.

Use this code to collect the object keys where the year is 2009:

var keys []string
for k, car := range v.Cars {
	if car.Details.Year == 2009 {
		keys = append(keys, k)
	}
}

huangapple
  • 本文由 发表于 2022年9月22日 21:12:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/73815285.html
匿名

发表评论

匿名网友

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

确定