检查 JSON 是对象还是数组
Check if JSON is Object or Array
Go 中是否有一种简单的方法来检查给定的 JSON 是对象 {}
还是数组 []
?
首先想到的是json.Unmarshal()
进入一个界面,然后看看是不是变成了一张图,还是一片图。但这似乎效率很低。
我可以只检查第一个字节是 {
还是 [
吗?或者是否有更好的方法已经存在。
使用以下代码检测 []byte
值 data
中的 JSON 文本是否为数组或对象:
// Get slice of data with optional leading whitespace removed.
// See RFC 7159, Section 2 for the definition of JSON whitespace.
x := bytes.TrimLeft(data, " \t\r\n")
isArray := len(x) > 0 && x[0] == '['
isObject := len(x) > 0 && x[0] == '{'
这段代码处理可选的前导空格,比解组整个值更有效。
因为 JSON 中的顶级值也可以是数字、字符串、布尔值或 nil,所以 isArray
和 isObject
的计算结果可能都为 false。当 JSON 无效时,值 isArray
和 isObject
也可以评估为 false。
使用类型开关确定类型。这类似于 Xay 的回答,但更简单:
var v interface{}
if err := json.Unmarshal(data, &v); err != nil {
// handle error
}
switch v := v.(type) {
case []interface{}:
// it's an array
case map[string]interface{}:
// it's an object
default:
// it's something else
}
使用 json.Decoder
逐步解析您的 JSON。这比其他答案有优势:
- 比解码整个值更有效
- 使用官方 JSON 解析规则,如果输入无效则生成标准错误。
请注意,此代码未经测试,但应该足以让您了解思路。如果需要,它还可以轻松扩展以检查数字、布尔值或字符串。
func jsonType(in io.Reader) (string, error) {
dec := json.NewDecoder(in)
// Get just the first valid JSON token from input
t, err := dec.Token()
if err != nil {
return "", err
}
if d, ok := t.(json.Delim); ok {
// The first token is a delimiter, so this is an array or an object
switch (d) {
case '[':
return "array", nil
case '{':
return "object", nil
default: // ] or }, shouldn't be possible
return "", errors.New("Unexpected delimiter")
}
}
return "", errors.New("Input does not represent a JSON object or array")
}
请注意,此 消耗了 in
的前几个字节。如有必要,reader 进行复制是一项练习。如果您尝试从字节切片 ([]byte
) 读取数据,请先将其转换为 reader:
t, err := jsonType(bytes.NewReader(myValue))
Go 中是否有一种简单的方法来检查给定的 JSON 是对象 {}
还是数组 []
?
首先想到的是json.Unmarshal()
进入一个界面,然后看看是不是变成了一张图,还是一片图。但这似乎效率很低。
我可以只检查第一个字节是 {
还是 [
吗?或者是否有更好的方法已经存在。
使用以下代码检测 []byte
值 data
中的 JSON 文本是否为数组或对象:
// Get slice of data with optional leading whitespace removed.
// See RFC 7159, Section 2 for the definition of JSON whitespace.
x := bytes.TrimLeft(data, " \t\r\n")
isArray := len(x) > 0 && x[0] == '['
isObject := len(x) > 0 && x[0] == '{'
这段代码处理可选的前导空格,比解组整个值更有效。
因为 JSON 中的顶级值也可以是数字、字符串、布尔值或 nil,所以 isArray
和 isObject
的计算结果可能都为 false。当 JSON 无效时,值 isArray
和 isObject
也可以评估为 false。
使用类型开关确定类型。这类似于 Xay 的回答,但更简单:
var v interface{}
if err := json.Unmarshal(data, &v); err != nil {
// handle error
}
switch v := v.(type) {
case []interface{}:
// it's an array
case map[string]interface{}:
// it's an object
default:
// it's something else
}
使用 json.Decoder
逐步解析您的 JSON。这比其他答案有优势:
- 比解码整个值更有效
- 使用官方 JSON 解析规则,如果输入无效则生成标准错误。
请注意,此代码未经测试,但应该足以让您了解思路。如果需要,它还可以轻松扩展以检查数字、布尔值或字符串。
func jsonType(in io.Reader) (string, error) {
dec := json.NewDecoder(in)
// Get just the first valid JSON token from input
t, err := dec.Token()
if err != nil {
return "", err
}
if d, ok := t.(json.Delim); ok {
// The first token is a delimiter, so this is an array or an object
switch (d) {
case '[':
return "array", nil
case '{':
return "object", nil
default: // ] or }, shouldn't be possible
return "", errors.New("Unexpected delimiter")
}
}
return "", errors.New("Input does not represent a JSON object or array")
}
请注意,此 消耗了 in
的前几个字节。如有必要,reader 进行复制是一项练习。如果您尝试从字节切片 ([]byte
) 读取数据,请先将其转换为 reader:
t, err := jsonType(bytes.NewReader(myValue))