簡體   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