SPL:读写 JSON 数据
JSON是一种容易理解的结构化数据格式,它经常以一个大字符串的形式在各种计算机语言中传递信息,SPL语言提供了json()函数加载/生成JSON,加载成序表、序列对象后,就方便做计算了。
加载JSON数据
JSON中有数组、对象、数值、字符串、布尔值(true、false)以及表示空值的null,SPL和JSON的对象及数据类型能比较好的对应起来。
基本数据类型
JSON里其它基本数据类型在SPL中都能直接对应上,A1中的定义了一个JSON字符串(SPL单元格中,用单引号开头定义字符串),各种类型的数据组成一个JSON数组:
A |
|
1 |
'["v1",66,true,false,null] |
2 |
=json(A1) |
JSON中没有专门的日期时间类型,传递日期时间数据时,可能是任意格式的格式化字符串,或数值类型的毫秒数:
A |
|
1 |
'["string","2021-01-02","2021/01/03 12:15",1632627573336,66] |
2 |
=json(A1) |
SPL中需要日期时间类型时,可以把加载进来的格式化字符串、数值用date()、datetime()等函数进行转换:
A |
|
3 |
=[date(A2(2)), datetime(A2(3),"yyyy/MM/dd HH:mm"), date(A2(4))] |
数组
上例中各种类型数据是放在一个JSON数组中,如下A1再定一个等差数列的JSON数组
A |
|
1 |
'[11,13,15,17] |
2 |
=json(A1) |
对象
如下A1是一个JSON对象:
A |
|
1 |
'{"n1":"v1","n2":"v2","n3":"v3"} |
2 |
=json(A1) |
它加载成了一个单行的序表对象:
对象数组
很自然的,多个JSON对象组成一个数组后,就会加载成一个多行的序表对象:
A |
|
1 |
'[{"n1":"v1","n2":"v2","n3":"v3"}, {n1:"v4",n2:"v5",n3:"v6"}, {"n1":"v7","n2":"v8","n3":"v9"}] |
2 |
=json(A1) |
另外,注意第二行的属性名没有双引号,这不符合JSON规范,但没按错误处理,也能正常解析出属性名:
不同结构对象数组
JSON数组中的多个对象,可能是异构的,第一个对象里没有n3属性,第二个对象里没有n1属性,第三个对象里没有n2属性:
A |
|
1 |
'[{n1:"v1",n2:"v2"},{n2:"v5",n3:"v6"},{n1:"v7",n3:"v9"}] |
2 |
=json@t(A1) |
这种情况转换成序表时,会以所有JSON对象属性的合集为结构。JSON对象中缺失的值补为null,这样规范处理后,有利于后续计算。
嵌套数组及对象
JSON数组中的元素不限制数据类型,甚至可以是嵌套的数组、对象:
A |
|
1 |
'[[1,2,3],{"n1":"v1","n2":"v2","n3":"v3"},"v1",66,true,null] |
2 |
=json(A1) |
序列同样也支持混合类型,第一个元素同样是序列,第二个元素是序表:
同理,JSON对象中的属性值,同样也可以嵌套数组、对象:
A |
|
1 |
'{"n1":"v1","n2":[1,2,3],"n3":{"n31":"v31","n32":"v32","n33":"v33"}} |
2 |
=json(A1) |
数组、对象灵活嵌套后,形成多级结构化数据,JSON和SPL都容易表达它们。
生成JSON字符串
加载的反向操作是生成JSON字符串,SPL中仍然用json()函数实现它,A2中把A1的JSON字符串加载成SPL对象;A3中把A2的SPL对象再转换回JSON字符串,json()函数判断传入参数的类型,会自动的选择正确的转换动作(传入JSON字符串时,转换成SPL对象;传入SPL对象时,转换成JSON字符串)。
A |
|
1 |
'[[1,2,3],{"n1":"v1","n2":"v2","n3":"v3"},"v1",66,true,null] |
2 |
=json(A1) |
3 |
=json(A2) |
执行后,观察A3的值,能看到是和A1一样的JSON字符串:
[[1,2,3],{"n1":"v1","n2":"v2","n3":"v3"},"v1",66,true,null]
下面看生成JSON字符串时,SPL对象与JSON对象的对应关系。
基本数据类型
A |
|
1 |
=["str",22,true,false,null,date(2021,9,18)] |
2 |
=json(A1) |
A1生成的SPL序列中,除了JSON支持的基本数据类型外,最后还有一个日期类型,转成JSON字符串时,它会被格式化成字符串类型:
数组
A1生成一个SPL序列,A2用json()函数把它生成JSON字符串
A |
|
1 |
=["a","b","c"] |
2 |
=json(A1) |
对象
A1创建了以n1,n2,n3为结构的空序表,A2向A1中插入两条数据
A |
|
1 |
=create(n1,n2,n3) |
2 |
>A1.insert(0,"v1","v2","v3"),A1.insert(0,"v4","v5","v6") |
3 |
=json(A1(2)) |
A1中的每一条记录对应一个JSON对象,A3中把第二条记录转换成JSON字符串
对象数组
把SPL序列、序表写出时,会转成JSON数组,以上一节的序表为例,A3中把整个序表写出,最终结果是JSON对象数组
A |
|
1 |
=create(n1,n2,n3) |
2 |
>A1.insert(0,"v1","v2","v3"),A1.insert(0,"v4","v5","v6") |
3 |
=json(A1) |
嵌套数组及对象
A |
|
1 |
=create(n1,n2,n3) |
2 |
>A1.insert(0,"v1","v2","v3") |
3 |
=create(f1,f2) |
4 |
>A3.insert(0,22,A1) |
5 |
=json(A3) |
A3中生成如下嵌套的序表:
A5中生成如下JSON字符串:
格式化一下就看的更清楚,即便内外两层序表中都只有一行数据,都生成了数组:
[{
"f1": 22,
"f2": [{
"n1": "v1",
"n2": "v2",
"n3": "v3"
}]
}]
有时期望这种单行的直接生成如下的对象,而非对象数组,把序表换成记录就可以了(A1、A3是序表,A1(1)、A3(1)是它们的第一条记录):
{
"f1": 22,
"f2": {
"n1": "v1",
"n2": "v2",
"n3": "v3"
}
}
A |
|
1 |
=create(n1,n2,n3) |
2 |
>A1.insert(0,"v1","v2","v3") |
3 |
=create(f1,f2) |
4 |
>A3.insert(0,22,A1(1)) |
5 |
=json(A3(1)) |