在Golang中像JavaScript一样过滤JSON
在Golang中像JavaScript一样过滤JSON 我正在尝试过滤JSON,但在Go中还没有找到任何简单的方法来实现这一点。是否有内置的方法可以做到这一点?或者我如何使用Go来实现这个功能?最好不使用结构体。
![]()
Edit fiddle - JSFiddle - Code Playground
使用JSFiddle代码编辑器在线测试你的JavaScript、CSS、HTML或CoffeeScript。
更多关于在Golang中像JavaScript一样过滤JSON的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我特别喜欢关于检查错误的评论!
更多关于在Golang中像JavaScript一样过滤JSON的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这可能是一个愚蠢的问题。但是否有可能将错误检查移到 func filter(predicate func(Item) 中?
Dean_Davidson:
有什么理由让你不直接使用
json.Marshal吗?
是的,是因为我缺乏相关知识。但你补充的这几行,加上 @mje 的帮助,确实对我很有用。谢谢你们两位!
Dean 的错误检查是为了处理来自 json.Marshal 的错误。在调用 json.Marshal 之前运行的 filter 中,你期望出现什么错误呢?显式的错误检查是 Go 编码的基础,所以如果你的问题基于此,你不应该试图避免它。
引用 mje:
使用 map 替代 struct,如你所愿:
思路正确,谢谢!但我不明白如何从中获取有效的 JSON 到变量里?
[]main.Item{main.Item{"row":"Home", "sub":"home"}, main.Item{"row":"Test", "sub":"home"}}
像这样
[{"sub":"home","row":"Home"},{"sub":"home","row":"Test"}]
是否有理由不直接使用 json.Marshal 呢?在 @mje 提供的上一个优秀 Playground 链接基础上,你可以这样做:
json, err := json.Marshal(filter(makePredicate("home"), data))
if err != nil {
fmt.Println("Error:", err.Error)
}
fmt.Printf("%s\n", json)
这将得到:
[{“row”:“Home”,“sub”:“home”},{“row”:“Test”,“sub”:“home”}]
以下是 Jeff 解决方案的更新版本:
在Go中过滤JSON数据可以通过encoding/json包结合map[string]interface{}或[]interface{}来实现。以下是一个不使用结构体的示例,通过递归函数过滤JSON中的特定字段:
package main
import (
"encoding/json"
"fmt"
)
func filterJSON(data interface{}, keys []string) interface{} {
switch v := data.(type) {
case map[string]interface{}:
result := make(map[string]interface{})
for key, value := range v {
for _, k := range keys {
if key == k {
result[key] = filterJSON(value, keys)
}
}
}
return result
case []interface{}:
var result []interface{}
for _, item := range v {
result = append(result, filterJSON(item, keys))
}
return result
default:
return v
}
}
func main() {
jsonStr := `{
"name": "John",
"age": 30,
"address": {
"city": "New York",
"zip": "10001"
},
"hobbies": ["reading", "gaming"]
}`
var data interface{}
json.Unmarshal([]byte(jsonStr), &data)
filtered := filterJSON(data, []string{"name", "city"})
output, _ := json.MarshalIndent(filtered, "", " ")
fmt.Println(string(output))
}
输出结果:
{
"name": "John",
"address": {
"city": "New York"
}
}
对于更复杂的过滤条件(如值比较),可以修改filterJSON函数:
func filterByValue(data interface{}, key string, targetValue interface{}) interface{} {
switch v := data.(type) {
case map[string]interface{}:
if val, exists := v[key]; exists && val == targetValue {
return v
}
result := make(map[string]interface{})
for k, value := range v {
filtered := filterByValue(value, key, targetValue)
if filtered != nil {
result[k] = filtered
}
}
if len(result) > 0 {
return result
}
case []interface{}:
var result []interface{}
for _, item := range v {
filtered := filterByValue(item, key, targetValue)
if filtered != nil {
result = append(result, filtered)
}
}
return result
}
return nil
}
使用示例:
func main() {
jsonStr := `[
{"name": "John", "age": 30},
{"name": "Jane", "age": 25}
]`
var data interface{}
json.Unmarshal([]byte(jsonStr), &data)
filtered := filterByValue(data, "age", 25)
output, _ := json.MarshalIndent(filtered, "", " ")
fmt.Println(string(output))
}
输出:
[
{
"name": "Jane",
"age": 25
}
]
这些方法通过类型断言和递归处理实现了JSON数据的动态过滤,无需预定义结构体。



