One possible solution to this:
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
jq -n --argjson n "${#aliases[@]}" '
{ compileroption: {
baseurl: ".",
paths:
(
reduce range($n) as $i ({};
.[$ARGS.positional[$i]] = [$ARGS.positional[$i+$n]]
)
)
} }' --args "${!aliases[@]}" "${aliases[@]}"
Does not use jo
and instead pass the keys and values of the associative array aliases
into jq
as positional parameters with --args
at the end of the command (--args
must always be the last option, if it's used at all). The jq
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 a reduce
operation over a range of $n
integers from zero up, where $n
is the number of elements in the aliases
array. The reduce
operation builds the paths
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:
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
for key in "${!aliases[@]}"; do
jo "$key[]=${aliases[$key]}"
done
This would output the three objects
{"Icons":["components/Icons/Exports"]}
{"Index":["components/Index/Exports"]}
{"Shared":["components/Shared/Exports"]}
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 of jo
like so:
for key in "${!aliases[@]}"; do
jq -n --arg key "$key" --arg value "${aliases[$key]}" '.[$key] = [$value]'
done
We may then read these and add them in the correct place in the object we're creating in jq
:
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
for key in "${!aliases[@]}"; do
jo "$key[]=${aliases[$key]}"
done |
jq -n '{ compileroptions: {
baseURL: ".",
paths: (reduce inputs as $item ({}; . += $item)) } }'
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.