yq 的 min 操作符:求取标量序列最小值实战指南

📅 发布时间:2026/9/14 22:08:09
yq 的 min 操作符:求取标量序列最小值实战指南
yq 的 min 操作符求取标量序列最小值实战指南【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq导读本文围绕 yqportable command-line YAML/JSON/XML/CSV/TOML/HCL/properties 处理器中的min操作符展开讲解它如何在传入的标量值序列中计算最小值。读完本文你将掌握min对整数、字符串的求值行为、对空序列的处理结果以及它底层与max、compare操作符共享的比较实现原理并能在真实管道中组合使用该操作符。min 操作符是什么min是 yq 表达式语言中一个零参数NumArgs: 0的操作符其功能是计算传入的标量值序列中的最小值。该定义来自官方操作符文档 min.md是min唯一的核心语义。在 yq 中一个表达式的结果往往是一个由多个候选节点CandidateNode组成的序列。min会遍历这个序列并从中挑出在类型比较规则下“最小”的那一个作为结果返回。与之成对的是max操作符功能为求最大值二者实现几乎完全对称。求整数序列的最小值输入示例准备一个sample.yml文件内容为一个整数数组- 99 - 16 - 12 - 6 - 66执行命令yq min sample.yml输出结果6可以看到min对整数序列按数值大小比较返回了序列中最小的元素6而其他元素被丢弃。在 yq 的测试套件中该场景被描述为 Minimum int输入[99, 16, 12, 6, 66]期望输出为路径P[3]、类型!!int、值6的节点见 operators_compare_test.go。求字符串序列的最小值输入示例- foo - bar - baz执行命令yq min sample.yml输出结果bar字符串序列的最小值是按字典序逐个字符的字节大小比较得出的barbazfoo因此返回bar。对应测试场景 Minimum string 的期望输出为路径P[1]、类型!!str、值bar见 operators_compare_test.go。空序列上的 min无输出输入示例[]执行命令yq min sample.yml输出结果当输入为空序列没有任何标量元素时min不产生任何输出。对应测试场景 Minimum of empty 的期望结果为空列表见 operators_compare_test.go。这一点在编写脚本时要特别注意对空数据求 min 不会报错但也不会得到任何值下游管道需要自行处理“无结果”的情况。源码实现min 与 max 共用一套比较内核min在源码中位于 operator_compare.gofunc minOperator(d *dataTreeNavigator, context Context, _ *ExpressionNode) (Context, error) { log.Debug((Min)) return superlativeByComparison(d, context, compareTypePref{Greater: false}) } func maxOperator(d *dataTreeNavigator, context Context, _ *ExpressionNode) (Context, error) { log.Debug((Max)) return superlativeByComparison(d, context, compareTypePref{Greater: true}) }两者的差别仅仅在于传入的compareTypePref.Greater布尔值min为false取更小者max为true取更大者。核心逻辑superlativeByComparisonoperator_compare.go执行以下步骤对当前上下文中每个匹配节点调用splat展开见 operator_traverse_path.go把容器节点铺平为元素序列以序列第一个元素为临时“最值”依次与后续每个元素调用compare(prefs)比较函数若当前元素比已记录的“最值”更符合条件对 min 而言是更小则替换记录最终把每个序列求得的最值节点收集进结果列表返回。支持的类型与比较规则compare(prefs)内部的compareScalarsoperator_compare.go按节点标签Tag分派比较!!intvs!!int解析为 int64 后按数值比较!!int/!!float混合解析为 float64 后按数值比较因此整数与浮点数可以直接混排求 min!!strvs!!str按字符串值直接比较字典序!!timestamp或可解析为时间戳的字符串走compareDateTimeoperator_compare.go按时间先后比较时间布局取自当前上下文context.GetDateTimeLayout()映射MappingNode与数组SequenceNode不支持参与比较会返回 maps not yet supported for comparison / arrays not yet supported for comparison 错误!!null与任何非空值比较均返回false两者都为 null 时仅在OrEqual语义下返回真。这意味着min并不仅限于文档示例中的整数与字符串日期时间序列同样可以直接求最小值但映射、数组等复合结构会直接报错使用时需先对嵌套结构进行展开或选取。操作符注册语法层面如何绑定 min在词法与解析层面min被注册为独立操作类型见 operation.govar minOpType operationType{Type: MIN, NumArgs: 0, Precedence: 40, Handler: minOperator} var maxOpType operationType{Type: MAX, NumArgs: 0, Precedence: 40, Handler: maxOperator}其中NumArgs: 0说明min不接收参数对应文档中直接以yq min调用的用法Precedence: 40决定了它与其他操作符组合时的结合优先级Handler指向上述minOperator实现。因此你可以在管道中把它与其他表达式组合例如先筛选再求最值# 从对象数组中取出 scores 字段再求最小值 yq [.items[].score] | min data.yaml小结min是 yq 中最常用的聚合操作符之一对整数、浮点数、字符串、时间戳等标量序列按各自的类型规则取最小值对空序列返回空结果对复合结构映射/数组则报错。其实现与max共用superlativeByComparison比较内核仅由一个布尔标志区分大小方向理解这一点后你就能把min/max灵活嵌入到自己的 YAML 处理管道中。【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考