首页 > 解决方案 > 根据特定键提取字符串值数组

问题描述

我希望每个人都很好。

我正在努力使用 JQ 尝试使用特定键从输入 json 中选择字符串值数组。"key":["string1",... , "stringn"] 可以嵌入到 json 中任何深度的“某处”。我只知道数组的键值。

假设我有一些 json,其中包括键 dictionnay (dict) 和 json source (source)。在这个例子中,我想选择“key4”和“key11”数组并将它们放入带有相应键的结果 json 中。

我的示例输入是:

 {
    "dict": ["key4", "key11"],
    "source":{
    "key0": {
        "key1": "valueA",
        "key2": 123456,
        "key3": [{
                "key4": ["anotherValue4341", "anotherValue4342"],
                "key5": [{
                    "someKey351": "someValue351"
                }, {
                    "someKey352": "someValue352"
                }],
                "key6": 999
            },
            {
                "key7": "anotherValue342",
                "key8": "anotherValue352",
                "key9": 666
            }
        ],
        "key10": {
            "key11": ["lastvalue111", "lastvalue112", "lastvalue113"]
        }
    }

}}

我对这个样本的预期输出是:

{
    "key4": ["anotherValue4341", "anotherValue4342"],
    "key11": ["lastvalue111", "lastvalue112", "lastvalue113"]
}

我正在使用 JQ 来提取请求的输出。

现在我试图重用以前的查询来选择这样的键/值:

jq '.dict as $dict | .source | reduce paths as $p (.;getpath($p) as $v| if $v|type == "string" and $dict[$v] then setpath($p; $dict[$v]) else . end)'

但它似乎与一些值斗争:jq:错误(在:26):无法使用字符串“valueA”索引数组

我还尝试选择包含 dict 中的键的匹配对象:

jq '.dict as $dict | .source | recurse(.[]?) | objects | select(in($dict))'

但这会导致错误“无法检查数组是否有对象键”

我希望我足够清楚地解释我的需求/问题。

任何提示表示赞赏。

标签: jsonjq

解决方案


为简单起见,我们首先假设核心任务是获取与一个特定键关联的值。为了说明和清楚起见,让我们相应地定义一个函数:

# Emit a (possibly empty) stream of key-value objects 
# corresponding to the $key specified as a string
def getKeyValue($key):
  .. | objects | select(has($key)) | {($key): .[$key]};

这个问题的解决方案现在很简单:

[.dict[] as $k | getKeyValue($k)] | add

变化

这个解决方案有几个潜在的问题:

  • 输入中可能根本没有出现一个或多个感兴趣的键;

  • 一个或多个感兴趣的键可能在输入中出现不止一次;

  • 如果输入很大,那么更有效的解决方案可能更可取。

前两个问题很容易解决,但具体要根据具体要求而定。效率问题同样可以通过修改 getKeyValue 的 def 来轻松解决,以便命名参数是一个字符串数组。


推荐阅读