JQ如何按相邻值间隔分割数组并统计各分段长度
会话长度统计JQ实现方案
需求规则
根据用户单次访问的时间戳数组统计各会话长度,判定规则:相邻时间戳的间隔时长大于limit阈值时,即判定开启新会话。
示例
- 输入:类纪元秒格式的时间戳数组
[ 101, 102, 105, 116, 128, 129, 140, 145, 146, 152 ]
- 参数设置:
limit=10 - 期望输出:各会话分段长度数组
[ 3, 1, 2, 4 ]
实现代码
可复用脚本版本
将以下代码保存为.jq后缀的脚本文件,支持通过--argjson传入自定义阈值:
def count_session_lengths($limit): reduce .[] as $ts ( {prev: null, sessions: []}; if .prev == null then {prev: $ts, sessions: [1]} elif ($ts - .prev) > $limit then {prev: $ts, sessions: .sessions + [1]} else {prev: $ts, sessions: (.sessions | .[-1] += 1)} end ) | .sessions; count_session_lengths($limit)
调用命令示例:
jq --argjson limit 10 -f session_count.jq timestamps.json
命令行单行版本
不需要单独存脚本文件时,可以直接在命令行执行单行命令:
jq --argjson limit 10 'reduce .[] as $ts ({prev:null,sessions:[]}; if .prev==null then {prev:$ts,sessions:[1]} elif ($ts-.prev)>$limit then {prev:$ts,sessions:.sessions+[1]} else {prev:$ts,sessions:(.sessions|.[-1]+=1)} end) | .sessions' timestamps.json
实现逻辑说明:遍历时间戳数组时全程记录上一个访问时间戳:
- 读取第一个时间戳时直接初始化第一个会话,初始长度为1
- 每读取到新的时间戳,先计算和上一个时间戳的差值,差值超过
limit就新建一个长度为1的会话项- 差值未超过阈值就给当前正在统计的最后一个会话的长度计数加1
- 遍历完成后直接输出所有会话的长度数组即可
内容的提问来源于stack exchange,提问作者wass rubleff
相关产品推荐
相关产品推荐

