yq 的 max 操作符:从序列中求最大值(整数 / 字符串 / 日期时间)

发布时间:2026/9/14 3:14:27
yq 的 max 操作符:从序列中求最大值(整数 / 字符串 / 日期时间) yq 的 max 操作符从序列中求最大值整数 / 字符串 / 日期时间【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq本文讲解 yq 中用于计算序列最大值的max操作符它作用于流入的标量值序列Sequence返回其中的最大值。无论你的数据是整数列表、字符串列表还是混合数值max都能按类型规则正确求出极值遇到空序列时则返回空结果。读完本文你将掌握max的完整用法、类型比较规则及其底层实现原理并能把它与其他操作符组合在真实 YAML/JSON 数据处理场景中直接使用。max 操作符是什么根据官方操作符文档pkg/yqlib/doc/operators/max.md的定义Computes the maximum among an incoming sequence of scalar values.即在一串进入操作符的标量值序列中计算最大值。max是一个零参数操作符直接写作yq max sample.yml它的语法由词法分析器注册为简单操作符见 pkg/yqlib/lexer_participle.go 中的simpleOp(max, maxOpType)在操作符注册表中对应MAX类型优先级为 40与比较操作符 同级见 pkg/yqlib/operation.go。求整数的最大值给定一个sample.yml文件内容为- 99 - 16 - 12 - 6 - 66执行yq max sample.yml输出99这是最典型的用法对顶层序列中的所有整数取最大者。求字符串的最大值max同样适用于字符串序列。给定sample.yml- foo - bar - baz执行yq max sample.yml输出foo字符串比较按字典序进行fASCII 102大于bASCII 98因此foo胜出。若多个字符串完全相同max返回序列中第一个出现的最大值元素。空序列返回空给定一个空数组sample.yml[]执行yq max sample.yml输出为空无任何结果。这符合直觉空序列中没有可比较的元素自然求不出最大值。测试用例中同样验证了这一行为见下文测试用例验证一节。底层原理max 是如何算出来的从源码看max的实现位于 pkg/yqlib/operator_compare.gofunc maxOperator(d *dataTreeNavigator, context Context, _ *ExpressionNode) (Context, error) { log.Debug((Max)) return superlativeByComparison(d, context, compareTypePref{Greater: true}) }它复用了与min相同的极值算法superlativeByComparisonoperator_compare.go区别仅在于比较偏好compareTypePref{Greater: true}——max在遍历中不断用大于判定替换当前结果最终留下最大的那个。核心流程如下对上下文中的每个匹配节点执行splat展开把序列或遍历得到的多个节点拆成一组候选标量取第一个元素作为初始最大值依次与其余元素比较凡是el 当前结果成立就替换当前结果最后把最大值放入结果上下文。max支持的类型由底层比较函数compareScalarsoperator_compare.go决定与比较操作符 共享同一套类型规则整数与整数按 64 位整数数值比较parseInt64整数 / 浮点混合统一转成 float64 后比较strconv.ParseFloat因此max可同时处理int与float混合序列字符串与字符串按字节序字典序比较日期时间若值为!!timestamp标签或字符串可按当前日期时间布局默认 RFC3339解析则按时间先后比较null 参与比较时返回 false即 null 不会被选为最大值。由于数组与 map 在比较操作中不被支持operator_compare.go 会返回 arrays not yet supported for comparison 之类的错误max作用于标量序列这与文档中incoming sequence of scalar values的定义完全一致。测试用例验证max的行为在 pkg/yqlib/operators_compare_test.go 中有三组明确的测试场景与文档示例一一对应场景输入文档表达式期望结果Maximum int[99, 16, 12, 6, 66]maxD0, P[0], (!!int)::99Maximum string[foo, bar, baz]maxD0, P[0], (!!str)::fooMaximum of empty[]max无输出注意测试输出中的P[0]它表示最大值元素在原始序列中的路径下标也就是原始位置索引——即使元素被复制为结果其来源路径依然保留方便后续结合路径信息做进一步处理。(!!int)/(!!str)是 YAML 标签标明返回值的类型。测试通过TestMaxOperatorScenariosoperators_compare_test.go驱动并借助documentOperatorScenarios把场景同步生成到官方文档保证了文档示例与代码行为的一致性。实战组合在对象或嵌套结构中求最大max不限于顶层序列。由于它处理的是流入的序列可以把它放在管道右侧先筛选/收集出序列再求最大值。例如给定一个包含若干对象字段的 YAML- name: alpha score: 88 - name: beta score: 95 - name: gamma score: 72提取所有score再求最大yq [.[].score] | max sample.yml输出95这里[.[].score]先把各对象的score收集为一个新序列再交给max。同理可以用map(.price)或group_by配合max在分组成员内求极值。由于max与min、比较操作符共用比较内核pkg/yqlib/operator_compare.go你可以在同一份数据上同时用max/min计算上下界两者的类型支持完全对称。小结max计算流入序列中标量值的最大值语法为yq max file支持整数、浮点、字符串与日期时间比较null 不参与取胜空序列返回空结果底层复用比较操作符的compareScalars内核通过compareTypePref{Greater: true}与min区分源码与测试路径pkg/yqlib/operator_compare.go、pkg/yqlib/operators_compare_test.go、pkg/yqlib/operation.go。如需了解min最小值操作符、比较操作符 的完整语义可继续阅读仓库中的 pkg/yqlib/doc/operators/compare.md 与 pkg/yqlib/doc/operators/min.md。【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考