簡體   English   中英

如何使用 jq 和 map 從復雜的 JSON 中獲取對象的鍵值對? (活動活動)

[英]How to get key value pairs of the objects from complex JSON using jq and map? (Active Campaign)

我有以下 JSON。我想根據他們的角色獲取鍵值對對象。 在此示例中,有 3 個角色(Presenter、Approver、Customer),但可以有更多,因為它是動態的。

JSON

{
   "Presenter Name": "Roney",
   "Presenter Email": "roney@domain.com",
   "Approver Name": "Tim",
   "Approver Email": "tim@domain.com",
   "Customer Name": "Alex",
   "Customer Email": "alex@domain.com",   
   "Invoice": "001",
   "Date": "2022-02-14"   
}

預計 output 使用 jq,map,

{
    "Presenter": {
      "email_address": "roney@domain.com",
      "name": "Roney",
      "role": "Presenter"
    },
    "Approver": {
      "email_address": "tim@domain.com",
      "name": "Tim",
      "role": "Approver"
    },
    "Customer": {
      "email_address": "alex@domain.com",
      "name": "Alex",
      "role": "Customer"
    }
}

我已經嘗試過,但不知道下一步該怎么做。 請指教。

to_entries |map( { (.key): { name: .value, email_address:.value, role: .key} } ) | add

這會在空格字符處split鍵,同時丟棄其中沒有的任何項目。 然后它將三個字段相應地分配給它們的值,使用reduce組合分組。

to_entries
| map(.key |= split(" ") | select(.key[1]))
| reduce group_by(.key[0])[] as $g ({};
    .[$g[0].key[0]] = (
      INDEX($g[]; .key[1]) | {
        email_address: .Email.value,
        name: .Name.value,
        role: .Name.key[0]
      }
    )
  )
{
  "Approver": {
    "email_address": "tim@domain.com",
    "name": "Tim",
    "role": "Approver"
  },
  "Customer": {
    "email_address": "alex@domain.com",
    "name": "Alex",
    "role": "Customer"
  },
  "Presenter": {
    "email_address": "roney@domain.com",
    "name": "Roney",
    "role": "Presenter"
  }
}

演示

這是另一種不使用group_by的較短方法。 相反,這會使用reduce直接迭代初始的 object,如果鍵遵循以空格分隔的角色鍵模式,則立即相應地設置所有字段。

reduce (to_entries[] | .key /= " ") as {key: [$role, $key], $value} ({};
  if $key then
    .[$role] += {({Email: "email_address", Name: "name"}[$key]): $value, $role}
  else . end
)
{
  "Presenter": {
    "name": "Roney",
    "role": "Presenter",
    "email_address": "roney@domain.com"
  },
  "Approver": {
    "name": "Tim",
    "role": "Approver",
    "email_address": "tim@domain.com"
  },
  "Customer": {
    "name": "Alex",
    "role": "Customer",
    "email_address": "alex@domain.com"
  }
}

演示

{ "Name": "name",  "Email": "email_address" } as $key_map |
to_entries |
map (
   ( .key | split(" ") | select( length == 2 ) ) as [ $role, $raw_key ] |
   [ $role, "role",             $role  ],
   [ $role, $key_map[$raw_key], .value ]
) |
reduce .[] as [ $role, $key, $val ] ( {}; .[ $role ][ $key ] = $val )

jqplay上的演示


在上面,我們從使數據統一開始。 具體來說,我們首先制作以下內容:

[
   [ "Presenter", "role",          "Presenter"        ],
   [ "Presenter", "name",          "Roney"            ],
   [ "Presenter", "role",          "Presenter"        ],
   [ "Presenter", "email_address", "roney@domain.com" ],
   [ "Approver",  "role",          "Approver"         ],
   [ "Approver",  "name",          "Tim"              ],
   [ "Approver",  "role",          "Approver"         ],
   [ "Approver",  "email_address", "tim@domain.com"   ],
   [ "Customer",  "role",          "Customer"         ],
   [ "Customer",  "name",          "Alex"             ],
   [ "Customer",  "role",          "Customer"         ],
   [ "Customer",  "email_address", "alex@domain.com"  ]
]

有多余的信息,但這並不重要。

然后,最終的簡單reduce構建所需的結構。


.key | split(" ") | select( length == 2 )

可以換成更安全的

.key | match("^(.*) (Name|Email)$") | .captures | map( .string )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM