From ed63755d1f2aa93f8ebec575738b720843605900 Mon Sep 17 00:00:00 2001 From: pkoppstein Date: Mon, 31 Jul 2023 08:32:53 -0400 Subject: [PATCH] builtin.jq: revamp walk/1 Resolves #2584; also resolves #2611 and supersedes https://github.com/jqlang/jq/pull/2655 Note that according to the revised implementation: `{x:0} | walk(.,1)` is equivalent to `{x:0} | walk(.), walk(1)` --- src/builtin.jq | 15 ++++++++------- tests/jq.test | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/builtin.jq b/src/builtin.jq index e74e9771dc..1e23a2ed66 100644 --- a/src/builtin.jq +++ b/src/builtin.jq @@ -246,13 +246,14 @@ def bsearch($target): # Apply f to composite entities recursively, and to atoms def walk(f): - . as $in - | if type == "object" then - reduce keys_unsorted[] as $key - ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f - elif type == "array" then map( walk(f) ) | f - else f - end; + def w: + if type == "object" + then map_values(w) + elif type == "array" then map(w) + else . + end + | f; + w; # pathexps could be a stream of dot-paths def pick(pathexps): diff --git a/tests/jq.test b/tests/jq.test index 55630a5a43..de92a8b91c 100644 --- a/tests/jq.test +++ b/tests/jq.test @@ -1968,3 +1968,22 @@ implode|explode map(try implode catch .) [123,["a"],[nan]] ["implode input must be an array","string (\"a\") can't be imploded, unicode codepoint needs to be numeric","number (null) can't be imploded, unicode codepoint needs to be numeric"] + +# walk +walk(.) +{"x":0} +{"x":0} + +walk(1) +{"x":0} +1 + +# The following is a regression test, not a requirement: +[walk(.,1)] +{"x":0} +[{"x":0},1] + +# Issue #2584 +walk(select(IN({}, []) | not)) +{"a":1,"b":[]} +{"a":1}