Search code examples
jsonjq

Value map with JQ


I've a large JSON file where I'd like to transform some values based on some kind of mapping.

The data I have looks like:

[
    {"id":1, "value":"yes"},
    {"id":2, "value":"no"},
    {"id":3, "value":"maybe"}
]

And I'd like to transform that into a list like this:

[
    {"id":1, "value":"10"},
    {"id":2, "value":"0"},
    {"id":3, "value":"5"}
]

With the fixed mapping:

yes => 10
no => 0
maybe => 5

My current solution is based on a simple if-elif-else combination like this:

cat data.json| jq '.data[] | .value = (if .value == "yes" then "10" elif .value == "maybe" then "5"  else "0" end)'

But this is really ugly and I'd love to have a more direct way to express the mapping.

Thanks for your help


Solution

  • If one wants to avoid having to specify the mapping on the command line, then the following two variants may be of interest.

    The first variant can be used with jq 1.3, jq 1.4 and jq 1.5:

    def mapping: {"yes":"10","no":"0","maybe":"5"};
    map(.value |=  mapping[.])
    

    The next variant uses the --argfile option (available since jq 1.4), and is of interest if the mapping object is available in a file:

    jq --argfile mapping mapping.jq 'map(.value |= $mapping[.])' data.json
    

    Finally, in jq 1.5, other alternatives based on import are also available (!).