skip to Main Content

How can this be achieved?

Those are inputs:

ARRAY=["keyA", "keyC", "keyE"]
JSON={
  "keyA": "valueA",
  "keyB": "valueB",
  "keyC": "valueC",
  "keyD": "valueD",
  "keyE": "valueE",
  "keyF": "valueF"
}

So basing on what I have in ARRAY (keys) how can I output corresponding keys and values from JSON in order to have TARGET_JSON like this:

TARGET_JSON={
  "keyA": "valueA",
  "keyC": "valueC",
  "keyE": "valueE"
}

4

Answers


  1. You can use the select function in jq to filter a JSON object based on the keys being in an array. for example
    jq ‘select(keys_unmatched(["name", "city"]) | not)’ file.json

    Login or Signup to reply.
  2. This is not JSON but javascript:

    $ node
    Welcome to Node.js v19.7.0.
    Type ".help" for more information.
    > ARRAY=["keyA", "keyC", "keyE"]
    [ 'keyA', 'keyC', 'keyE' ]
    > JSON={
    ...   "keyA": "valueA",
    ...   "keyB": "valueB",
    ...   "keyC": "valueC",
    ...   "keyD": "valueD",
    ...   "keyE": "valueE",
    ...   "keyF": "valueF"
    ... }
    {
      keyA: 'valueA',
      keyB: 'valueB',
      keyC: 'valueC',
      keyD: 'valueD',
      keyE: 'valueE',
      keyF: 'valueF'
    }
    > 
    > var j = {}
    > ARRAY.forEach(elt => j[elt] = JSON[elt] )
    > console.log(j)
    { keyA: 'valueA', keyC: 'valueC', keyE: 'valueE' }
    
    Login or Signup to reply.
  3. jq —-argjson a "$ARRAY" '
      def project($a): . as $in
      | reduce $a[] as $k (null;.[$k] =$in[$k]); 
      project($a)' <<< "$JSON"
    
    Login or Signup to reply.
  4. Here is one possible solution using reduce:

    . as $obj
    | reduce ["keyA", "keyC", "keyE"][] as $key (
        {}; .[$key] = $obj[$key]
    )
    

    Or with user-provided variables:

    jq --argjson keys '["keyA", "keyC", "keyE"]' '. as $obj
    | reduce $keys[] as $key ({}; .[$key] = $obj[$key])
    

    If you don’t care about the order of keys in the result (there is no inherent meaning to order of keys in JSON objects, because they are a bag of key-value pairs without order), then an alternative would be using with_entries, although it will be slower for large inputs:

    jq --argjson keys '["keyA", "keyC", "keyE"]' 'with_entries(select(.key | IN($keys[])))'
    

    but this could be avoided by building a lookup/index object first:

    jq --argjson keys '["keyA", "keyC", "keyE"]' 'INDEX($keys[]; .) as $keys
    | with_entries(select(.key | in($keys)))'
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search