json JQ -展平/展开具有不同键名的双重嵌套对象

hyrbngr7  于 2022-12-15  发布在  其他
关注(0)|答案(3)|浏览(159)

具有以下json结构:

{
    "outerDescription1": {
        "innerDescription1": {
            "otherProperties": 1,
            "items": [
                "arrayItem1",
                "arrayItem2"
            ]
        }
    },
    "outerDescription2": {
        "innerDescription2": {
            "otherProperties": 2,
            "items": [
                "arrayItem3",
                "arrayItem4"
            ]
        }
    }
}

我希望得到以下结果:

{
    "item": "arrayItem1",
    "outer": "outerDescription1",
    "inner": "innerDescription1",
    "otherProperties": 1
}
{
    "item": "arrayItem2",
    "outer": "outerDescription1",
    "inner": "innerDescription1",
    "otherProperties": 1
}
{
    "item": "arrayItem3",
    "outer": "outerDescription2",
    "inner": "innerDescription2",
    "otherProperties": 2
}
{
    "item": "arrayItem4",
    "outer": "outerDescription2",
    "inner": "innerDescription2",
    "otherProperties": 2
}

假设:有许多outerDescriptioninnerDescription密钥,并且它们在前面是未知的。
单层展开是很简单的,但是展开具有不同键的双重嵌套对象对我来说是一个挑战。
我能得到的最接近的答案是:

jq "with_entries(.value = {outer: .key} + .value)[]"

其结果是:

{                              
  "outer": "outerDescription1",
  "innerDescription1": {       
    "otherProperties": 1,      
    "items": [                 
      "arrayItem1",            
      "arrayItem2"             
    ]                          
  }                            
}                              
{                              
  "outer": "outerDescription2",
  "innerDescription2": {       
    "otherProperties": 2,      
    "items": [                 
      "arrayItem3",            
      "arrayItem4"             
    ]                          
  }                            
}

但是现在,如果不确切知道下一个嵌套键的名称,我就无法像outer被吞下一样进行第二次展开。
我用的是JQ 1.6

6pp0gazn

6pp0gazn1#

可以使用path查找相应的路径,使用getpath检索它们的值:

path(.[][].items[]) as $p
| {item: getpath($p), outer: $p[0], inner: $p[1]}
+ (getpath($p[:-2]) | del(.items))
{
  "item": "arrayItem1",
  "outer": "outerDescription1",
  "inner": "innerDescription1",
  "otherProperties": 1
}
{
  "item": "arrayItem2",
  "outer": "outerDescription1",
  "inner": "innerDescription1",
  "otherProperties": 1
}
{
  "item": "arrayItem3",
  "outer": "outerDescription2",
  "inner": "innerDescription2",
  "otherProperties": 2
}
{
  "item": "arrayItem4",
  "outer": "outerDescription2",
  "inner": "innerDescription2",
  "otherProperties": 2
}

Demo

tag5nh1u

tag5nh1u2#

下面是一个使用to_entries的简单解决方案:

to_entries[]
  | .key as $outer
  | .value
  | to_entries[]
  | .key as $inner
  | .value
  | .otherProperties as $otherProperties
  | .items[]
  | {item: ., $outer, $inner, $otherProperties}

或者,等价地但没有变量:

to_entries[]
  | {outer: .key} +
    ( .value | to_entries[] | {inner: .key} +
    ( .value | {otherProperties} +
    ( .items[] | {item: .} )))

如果键的顺序很重要,则可以(例如)添加{item, outer, inner, otherProperties}这样的表达式。

vuktfyat

vuktfyat3#

如果您知道items属性的名称,则以下等效程序的可读性很强:

to_entries[]
| { outer: .key, nested: (.value | to_entries[]) }
| { item: .nested.value.items[] }
    + { outer, inner: .nested.key }
    + (.nested.value | del(.items))
to_entries[]
| { outer: .key, nested: (.value | to_entries[]) }
| { item: .nested.value.items[], outer, inner: .nested.key }
    + (.nested.value | del(.items))
to_entries[]
| { outer: .key, nested: (.value | to_entries[]) }
| { outer }
+ (.nested
    | { inner: .key, item: .value.items[] }
    + (.value | del(.items))
)
| { item, outer, inner, otherProperties } # force property order
to_entries[]
| { outer: .key, nested: (.value | to_entries[]) }
| { outer }
+ (.nested
    | { inner: .key }
    + (.value | { item: .items[] } + del(.items))
)
| { item, outer, inner, otherProperties } # force property order

输出:

{
  "item": "arrayItem1",
  "outer": "outerDescription1",
  "inner": "innerDescription1",
  "otherProperties": 1
}
{
  "item": "arrayItem2",
  "outer": "outerDescription1",
  "inner": "innerDescription1",
  "otherProperties": 1
}
{
  "item": "arrayItem3",
  "outer": "outerDescription2",
  "inner": "innerDescription2",
  "otherProperties": 2
}
{
  "item": "arrayItem4",
  "outer": "outerDescription2",
  "inner": "innerDescription2",
  "otherProperties": 2
}

相关问题