繁体   English   中英

如何在jq中使用父object数据提取和修改内部数组对象

[英]how to extract and modify inner array objects with parent object data in jq

我们正在尝试格式化 json,类似于:

[
{"id": 1,
    "type": "A",
    "changes": [ 
        {"id": 12},
        {"id": 13}
    ],
    "wanted_key": "good",
    "unwanted_key": "aaa"
},
{"id": 2,
    "type": "A",
    "unwanted_key": "aaa"
},
{"id": 3,
    "type": "B",
    "changes": [
        {"id": 31},
        {"id": 32}
    ],
    "unwanted_key": "aaa",
    "unwanted_key2": "aaa"
},
{"id": 4,
    "type": "B",
    "unwanted_key3": "aaa"
},
null,
null,
{"id": 7}
]

变成这样的东西:

[
  {
    "id": 1,
    "type": "A",
    "wanted_key": true  # every record must have this key/value
  },
  {
    "id": 12,  # note: this was in the "changes" property of record id 1
    "type": "A",  # type should be the same type than record id 1
    "wanted_key": true
  },
  {
    "id": 13,  # note: this was in the "changes" property of record id 1
    "type": "A",  # type should be the same type than record id 1
    "wanted_key": true
  },
  {
    "id": 2,
    "type": "A",
    "wanted_key": true
  },
  {
    "id": 3,
    "type": "B",
    "wanted_key": true
  },
  {
    "id": 31,  # note: this was in the "changes" property of record id 3
    "type": "B",  # type should be the same type than record id 3
    "wanted_key": true
  },
  {
    "id": 32,  # note: this was in the "changes" property of record id 3
    "type": "B",  # type should be the same type than record id 3
    "wanted_key": true
  },
  {
    "id": 4,
    "type": "B",
    "wanted_key": true
  },
  {
    "id": 7,
    "type": "UNKN",  # records without a type should have this type
    "wanted_key": true
  }
]

到目前为止,我已经能够:

  • 删除 null 记录
  • 获取我们需要的默认密钥
  • 给没有类型的记录一个默认类型

我们缺少什么:

  • 从具有changes键的记录中,创建具有其父记录type的新记录
  • 将所有记录连接到一个数组中

不幸的是,我们不完全确定如何进行......任何帮助将不胜感激。

到目前为止,我们的 jq 是这样的: del(..|nulls) | map({id, type: (.type // "UNKN"), wanted_key: (true)}) | del(..|nulls) del(..|nulls) | map({id, type: (.type // "UNKN"), wanted_key: (true)}) | del(..|nulls)

这是我们的测试代码:

https://jqplay.org/s/eLAWwP1ha8P

以下应该有效:

map(select(values))
| map(., .type as $type | (.changes[]? + {$type}))
| map({id, type: (.type // "UNKN"), wanted_key: true})
  1. 只有 select 非空值
  2. 返回原始项目,后跟它们的内部更改数组(+ 外部类型)
  3. 提取 output 的 3 个属性

多个map调用通常可以组合起来,因此变为:

map(
    select(values)
    | ., (.type as $type | (.changes[]? + {$type}))
    | {id, type: (.type // "UNKN"), wanted_key: true}
)

没有变量的另一个选项:

map(
    select(values)
    | ., .changes[]? + {type}
    | {id, type: (.type // "UNKN"), wanted_key: true}
)
# or:
map(select(values))
| map(., .changes[]? + {type})
| map({id, type: (.type // "UNKN"), wanted_key: true})

甚至对未知类型有一个单独的标准化步骤:

map(select(values))
| map(.type //= "UNKN")
| map(., .changes[]? + {type})
| map({id, type, wanted_key: true})
# condensed to a single line:
map(select(values) | .type //= "UNKN" | ., .changes[]? + {type} | {id, type, wanted_key: true})

解释:

  1. Select 仅来自数组的非空值
  2. 如果未设置类型,则创建值为"UNKN"的属性
  3. 生成原始数组项,然后是使用父类型扩展的嵌套更改元素
  4. 重塑对象以仅包含属性 id、type 和 Wanted_key。

这是一种方法:

map(
  select(values)
  | (.type // "UNKN") as $type
  | ., .changes[]?
  | {id, $type, wanted_key: true}
)
[
  {
    "id": 1,
    "type": "A",
    "wanted_key": true
  },
  {
    "id": 12,
    "type": "A",
    "wanted_key": true
  },
  {
    "id": 13,
    "type": "A",
    "wanted_key": true
  },
  {
    "id": 2,
    "type": "A",
    "wanted_key": true
  },
  {
    "id": 3,
    "type": "B",
    "wanted_key": true
  },
  {
    "id": 31,
    "type": "B",
    "wanted_key": true
  },
  {
    "id": 32,
    "type": "B",
    "wanted_key": true
  },
  {
    "id": 4,
    "type": "B",
    "wanted_key": true
  },
  {
    "id": 7,
    "type": "UNKN",
    "wanted_key": true
  }
]

演示

像下面这样的东西应该工作

map( 
  select(type == "object") | 
  ( {id}, {id : ( .changes[]? .id )} ) + 
  { type: (.type // "UNKN"), wanted_key: true }
)

jq play -演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM