如何用JSLT遍历JSON数组并计算duration字段?
JSLT数组遍历与duration字段计算实现方案
问题背景
现有如下JSON数据:
{ "id": "12345", "date_open": "2021-09-09", "date_last_updated": "2021-09-21", "status": "open", "project_name": "Project:5", "office": [ { "name": "office_one", "completed": true, "required": true, "contact_date": "2021-09-13", "response_date": "2021-09-15", "completion_date": "2021-09-15" }, { "name": "office_two", "completed": true, "required": true, "contact_date": "2021-09-13", "response_date": "2021-09-21", "completion_date": "2021-09-21" }, { "name": "office_three", "completed": false, "required": false, "contact_date": null, "response_date": null, "completion_date": null }, { "name": "office_four", "completed": false, "required": true, "contact_date": "2021-08-23", "response_date": "2021-09-01", "completion_date": null } ] }
已实现days_open字段的计算逻辑:
let date_started = parse-time(.date_open, "yyyy-MM-dd") let date_last_update = parse-time(.date_last_updated, "yyyy-MM-dd") let days_open = ($date_last_update - $date_started) / 86400 { "days_open" : $days_open, * : . }
现在需要遍历office数组,为每个元素按以下规则添加duration字段:
- 当
required为true时:- 若
completion_date不为null,计算contact_date与completion_date的天数差 - 若
completion_date为null,计算contact_date与response_date的天数差 - 若
response_date也为null,计算contact_date与父对象date_last_updated的天数差
- 若
- 当
required为false时,duration设为null
实现方案
JSLT中遍历数组使用map函数,结合if-then-else条件判断即可实现需求。完整表达式如下:
let date_started = parse-time(.date_open, "yyyy-MM-dd") let date_last_update = parse-time(.date_last_updated, "yyyy-MM-dd") let days_open = ($date_last_update - $date_started) / 86400 { "days_open" : $days_open, "office": map(.office, function($item) { // 解析当前office项的contact_date(若存在) let contact_time = if ($item.contact_date) then parse-time($item.contact_date, "yyyy-MM-dd") else null // 根据规则确定结束时间 let end_time = if ($item.completion_date) then parse-time($item.completion_date, "yyyy-MM-dd") else if ($item.response_date) then parse-time($item.response_date, "yyyy-MM-dd") else $date_last_update // 计算duration let duration = if ($item.required and $item.contact_date) then ($end_time - $contact_time) / 86400 else null // 返回原字段+新增的duration { "duration": $duration, *: $item } }), // 保留原对象其他字段 * : . - "office" }
代码说明
- 变量复用:提前解析父对象的
date_last_update,避免在数组遍历中重复解析,提升效率 - 数组遍历:使用
map(.office, function($item) { ... })遍历office数组,对每个元素$item进行处理 - 条件判断:按优先级依次判断
completion_date、response_date,最后 fallback到父对象的date_last_update作为结束时间 - duration计算:仅当
required为true且contact_date不为空时计算天数差,否则设为null - 字段保留:使用
*: $item保留原office元素的所有字段,再新增duration;父对象部分用* : . - "office"保留除office外的原字段,避免重复输出
输出结果
执行上述表达式后,将得到符合要求的JSON结构:
{ "id": "12345", "date_open": "2021-09-09", "date_last_updated": "2021-09-21", "days_open": 12, "status": "open", "project_name": "Project:5", "office": [ { "name": "office_one", "completed": true, "required": true, "contact_date": "2021-09-13", "response_date": "2021-09-15", "completion_date": "2021-09-15", "duration": 2 }, { "name": "office_two", "completed": true, "required": true, "contact_date": "2021-09-13", "response_date": "2021-09-21", "completion_date": "2021-09-21", "duration": 8 }, { "name": "office_three", "completed": false, "required": false, "contact_date": null, "response_date": null, "completion_date": null, "duration": null }, { "name": "office_four", "completed": false, "required": true, "contact_date": "2021-08-23", "response_date": "2021-09-01", "completion_date": null, "duration": 9 } ] }
内容的提问来源于stack exchange,提问作者user20409421
相关产品推荐
相关产品推荐

