I know about How to create JSON from associative array but that's not my problem.
I have this associative array:
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
Now I need to convert this associative array into this JSON:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"Index": ["components/Index/Exports"],
"Shared": ["components/Shared/Exports"],
"Icons": ["components/Icons/Exports"],
}
}
}
I want to use jo
and jq
. But I can't come up with the nesting.
I tried this code:
jo -p compilerOptions[baseUrl]=. compilerOptions[paths]="$(jo -p a ${Aliases[@]})"
But it does not even run.
Best Answer
One possible solution to this:
Does not use
jo
and instead pass the keys and values of the associative arrayaliases
intojq
as positional parameters with--args
at the end of the command (--args
must always be the last option, if it's used at all). Thejq
utility receives the keys and values as a single array,$ARGS.positional
. This means the first half of the array contains the keys, and the second half of the array contains the corresponding values.The body of the
jq
expression creates the output object and uses areduce
operation over a range of$n
integers from zero up, where$n
is the number of elements in thealiases
array. Thereduce
operation builds thepaths
object by adding the positional arguments, one by one, using$i
:th argument as the key and the$i
+$n
:th argument as the element in the corresponding array value.A slightly different approach using
jo
to create leaf objects of each key-value pair of the associative array:This would output the three objects
Since we're using
jo
like this, we impose some obvious restrictions on the keys of the array (may not contain=
,[]
etc.)We could use
jq
in place ofjo
like so:We may then read these and add them in the correct place in the object we're creating in
jq
:The main difference here is that we don't pass stuff into
jq
as command line options, but rather as a stream of JSON objects.