SPL:递归合并字段值
除了常见的二维数据表,我们也会用到有着多层结构的数据文件。比如用来存储销售记录的 JSON 数据文件,可能按照时间、地点等维度分为多层数据结构,但是每层结构中都有销售额字段。如果我们想要取得所有的销售额字段值,就要用到递归运算了。
我们通过具体的例子看一下,如何对多层数据递归合并字段值。
【例 1】 根据 JSON 格式的销售数据,计算 2014 年的总销售额。文件部分数据如下:
[
{"YEAR":2013,"MONTH":7,"SALES": [
{"ID":10248,"CUSTOMERID":"VINET", … ,"SALES":2440},
{"ID":10249,"CUSTOMERID":"TOMSP", … ,"SALES":1863.4},
{"ID":10250,"CUSTOMERID":"HANAR", … ,"SALES":1813.0},
…
]},
{"YEAR":2013,"MONTH":8,"SALES": [
{"ID":10270,"CUSTOMERID":"WARTH", … ,"SALES":1376.0},
{"ID":10271,"CUSTOMERID":"SPLIR", … ,"SALES":48.0},
{"ID":10272,"CUSTOMERID":"RATTC", … ,"SALES":1456.0},
…
]},
…
]
在 SPL 中提供了函数 A.field@r()用于递归获取字段值。
SPL脚本如下:
A |
|
1 |
=json(file("sales.json").read()) |
2 |
=A1.select(YEAR==2014) |
3 |
=A2.field@r("SALES") |
4 |
=A3.sum(~.sum()) |
A1:导入 JSON 数据文件。
A2:选出 2014 年的销售记录。
A3:使用函数 A.field@r() 递归获取所有销售字段值。
A4:循环计算 2014 年每个月份的销售额,再计算总销售额。
【例 2】 下面是某时刻,新冠状病毒世界各地确诊人数的 JSON 数据,要统计世界确诊人数。文件部分数据如下:
[
{Region:"USA",Confirmed:[
{Region:"California",Confirmed:3671902},
{Region:"New York",Confirmed:1139740},
{Region:"Virginia",Confirmed:620801},
{Region:"Florida",Confirmed:2064525},
…
]},
{Region:"Brazil",Confirmed:[…]},
{Region:"India",Confirmed: […]},
{Region:"France",Confirmed: […]}
…
]
在这个例子中,有的国家只统计了全国人数,也有的国家统计到了每个州(省),还有统计到每个城市的。在这种情况下不能简单的将字段值循环求和,而要用到递归合并了。在 SPL 中提供了函数 A.conj@r() 用于递归合并序列成员。
SPL脚本如下:
A |
|
1 |
=json(file("COVID-19.json").read()) |
2 |
=A1.field@r("Confirmed") |
3 |
=A2.conj@r().sum() |
A1:导入 JSON 数据文件。
A2:使用函数 A.field@r() 递归获取所有确诊字段值。
A3:使用函数 A.conj@r() 递归合并所有确诊人数,再求和。