在嵌套值的条件下解析json并提取数组中的项

时间:2015-07-21 13:24:25

标签: json rest parsing conditional-statements jq

我已经在这里问了一个类似的问题 - Parse json and choose items\keys upon condition,但这一次略有不同。

这是示例:

[
  {
    "item1": "value123",
    "array0": [
      {
        "item2": "aaa"
      }
    ]
  },
  {
    "item1": "value456",
    "array1": [
      {
        "item2": "bbb"
      }
    ]
  },
  {
    "item1": "value789",
    "array2": [
      {
        "item2": "ccc"
      }
    ]
  }
]

我想获得“item1”的值,仅当“item2”具有特定值时才会显示。

让我们说如果item2等于“bbb”,那么我想要回来的就是“value456”。

我试图用jq解决它,就像它在上面提到的问题中对我有用一样,但无济于事,因为我无法从“我”搜索的“更高”级别提取值jq的选择和地图。

4 个答案:

答案 0 :(得分:2)

由于递归运算符..的神奇力量,可以使用更简单的解决方案:

jq -r '.[] | select(.. | .item2? == "bbb").item1'

基本上它的作用是,对于原始数组中的每个(.[])对象,仅选择(select)其中任何以递归方式(..)命名的键的{ {1}}等于.item2,然后选择所述对象的"bbb"属性。

答案 1 :(得分:0)

在jq手册中找到解决方案(#ifthenelse和#Objects) - http://stedolan.github.io/jq/manual

jq -r '{name1: .[].item1, name2: .[].array[].item2} | /
if .item2 == "bbb" then .name1 elif .item2 != "bbb" then empty else empty end'

答案 2 :(得分:0)

如果你发现......的魔力太强大了,以下内容可能会有用。它限制了对" item2"的搜索。键。

def some(condition): reduce .[] as $x
 (false; if . then . else $x|condition end);

.[]
| to_entries
| select( some( .value | (type == "array") and some(.item2 == "bbb")) )
| from_entries
| .item1

如果您的jq有任何/ 1,则使用它而不是某些/。

答案 3 :(得分:0)

以下是使用 tostream getpath

的解决方案
foreach (tostream|select(length==2)) as [$p,$v] (.;.;
  if $p[-1] == "item2" and $v == "bbb" then getpath($p[:-3]).item1 else empty end
)

编辑:我现在意识到foreach E as $X (.; .; R)形式的过滤器几乎总是被重写为E as $X | R所以上面的内容实际上就是

  (tostream | select(length==2)) as [$p,$v]
| if $p[-1] == "item2" and $v == "bbb" then getpath($p[:-3]).item1 else empty end