Golang获取非结构化JSON数组的长度

Golang获取非结构化JSON数组的长度 我有以下JSON文档:

docs = “Records” :[ “{“a”:“770959028”, “b”:“099898”, “c”:“load-generator-span”, “d”:{“random”:”",“randomtext”:"" }}\n", “{“a”:“770959028”, “b”:“099898”, “c”:“load-generator-span”, “d”:{“random”:”",“randomtext”:"" }}\n", “{“a”:“770959028”, “b”:“099898”, “c”:“load-generator-span”, “d”:{“random”:”",“randomtext”:"" }}\n", “{“a”:“770959028”, “b”:“099898”, “c”:“load-generator-span”, “d”:{“random”:”",“randomtext”:"" }}\n"]

我已经使用 json.Unmarshal([]byte(docs), &result) 将上述字符串反序列化,其中 result 是一个类似 var result map[string]interface{} 的映射。

现在我可以获取所有的 result[Records],但是我如何才能获取 result[Records] 的长度呢?len 函数对此不起作用,它给我报错,例如 invalid argument for len。有没有我可以使用的更好的函数?


更多关于Golang获取非结构化JSON数组的长度的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复
var result map[string]interface{}
json.Unmarshall([]byte(jsonInput), &result)
records, ok := result["Records"].([]interface{})
if !ok {
    panic("Not a slice")
}
count := len(records)

非常感谢。

更多关于Golang获取非结构化JSON数组的长度的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


由于您的代码格式不正确,很难判断您实际的 JSON 是什么样子,或者它可能被解析成什么 Go 值。

不过,如果您有一个 map[string]interface{} 并且知道对于给定的键,您有一个数据切片,那么您可以使用类型断言将该切片作为切片获取:

var result map[string]interface{}

json.Unmarshall([]byte(jsonInput), &result)

records, ok := result["Records"].([]interface{})
if !ok { panic("Not a slice") }

count := len(records)

在Go中处理非结构化JSON时,当result["Records"]的类型是interface{}时,直接使用len()函数确实会失败。你需要先进行类型断言,将其转换为切片类型后再获取长度。

以下是具体实现方法:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    docs := `{"Records": ["{\"a\":\"770959028\", \"b\":\"099898\", \"c\":\"load-generator-span\", \"d\":{\"random\":\"\",\"randomtext\":\"\" }}", "{\"a\":\"770959028\", \"b\":\"099898\", \"c\":\"load-generator-span\", \"d\":{\"random\":\"\",\"randomtext\":\"\" }}", "{\"a\":\"770959028\", \"b\":\"099898\", \"c\":\"load-generator-span\", \"d\":{\"random\":\"\",\"randomtext\":\"\" }}", "{\"a\":\"770959028\", \"b\":\"099898\", \"c\":\"load-generator-span\", \"d\":{\"random\":\"\",\"randomtext\":\"\" }}"]}`

    var result map[string]interface{}
    err := json.Unmarshal([]byte(docs), &result)
    if err != nil {
        panic(err)
    }

    // 方法1:直接类型断言
    if records, ok := result["Records"].([]interface{}); ok {
        fmt.Printf("Records数组长度: %d\n", len(records))
        
        // 遍历数组元素
        for i, record := range records {
            fmt.Printf("记录 %d: %v\n", i, record)
        }
    }

    // 方法2:更安全的类型检查
    records := result["Records"]
    switch v := records.(type) {
    case []interface{}:
        fmt.Printf("使用switch断言,长度: %d\n", len(v))
    case nil:
        fmt.Println("Records字段不存在或为null")
    default:
        fmt.Printf("Records字段类型不是数组: %T\n", v)
    }
}

如果你的JSON中Records数组包含的是字符串(如你提供的例子),你可以这样处理:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    docs := `{"Records": ["{\"a\":\"770959028\", \"b\":\"099898\", \"c\":\"load-generator-span\", \"d\":{\"random\":\"\",\"randomtext\":\"\" }}", "{\"a\":\"770959028\", \"b\":\"099898\", \"c\":\"load-generator-span\", \"d\":{\"random\":\"\",\"randomtext\":\"\" }}"]}`

    var result map[string]interface{}
    err := json.Unmarshal([]byte(docs), &result)
    if err != nil {
        panic(err)
    }

    // 获取Records数组
    if records, ok := result["Records"].([]interface{}); ok {
        fmt.Printf("数组长度: %d\n", len(records))
        
        // 处理数组中的每个JSON字符串
        for i, record := range records {
            if str, ok := record.(string); ok {
                // 可以进一步解析每个JSON字符串
                var item map[string]interface{}
                if err := json.Unmarshal([]byte(str), &item); err == nil {
                    fmt.Printf("记录 %d 的字段a: %v\n", i, item["a"])
                }
            }
        }
    }
}

输出结果:

数组长度: 4
记录 0 的字段a: 770959028
记录 1 的字段a: 770959028
记录 2 的字段a: 770959028
记录 3 的字段a: 770959028

关键点:

  1. 使用类型断言 result["Records"].([]interface{})interface{} 转换为切片
  2. 使用 ok 模式检查类型断言是否成功
  3. 转换成功后即可使用 len() 函数获取数组长度
回到顶部