bashassociative-array

How to combine associative arrays in bash?


Does anyone know of an elegant way to combine two associative arrays in bash just like you would a normal array? Here's what I'm talking about:

In bash you can combine two normal arrays as follows:

declare -ar array1=( 5 10 15 )
declare -ar array2=( 20 25 30 )
declare -ar array_both=( ${array1[@]} ${array2[@]} )

for item in ${array_both[@]}; do
    echo "Item: ${item}"
done

I want to do the same thing with two associative arrays, but the following code does not work:

declare -Ar array1=( [5]=true [10]=true [15]=true )
declare -Ar array2=( [20]=true [25]=true [30]=true )
declare -Ar array_both=( ${array1[@]} ${array2[@]} )

for key in ${!array_both[@]}; do
    echo "array_both[${key}]=${array_both[${key}]}"
done

It gives the following error:

./associative_arrays.sh: line 3: array_both: true: must use subscript when assigning associative array

The following is a work-around I came up with:

declare -Ar array1=( [5]=true [10]=true [15]=true )
declare -Ar array2=( [20]=true [25]=true [30]=true )
declare -A array_both=()

for key in ${!array1[@]}; do
    array_both+=( [${key}]=${array1[${key}]} )
done

for key in ${!array2[@]}; do
    array_both+=( [${key}]=${array2[${key}]} )
done

declare -r array_both

for key in ${!array_both[@]}; do
    echo "array_both[${key}]=${array_both[${key}]}"
done

But I was hoping that I'm actually missing some grammar that will allow the one-liner assignment as shown in the non-working example.

Thanks!


Solution

  • I don't have a one-liner either but here is a different 'workaround' that someone might like using string convertion. It's 4 lines, so I'm only 3 semi-colons from the answer you wanted!

    declare -Ar array1=( [5]=true [10]=true [15]=true )
    declare -Ar array2=( [20]=true [25]=true [30]=true )
    
    # convert associative arrays to string
    a1="$(declare -p array1)"
    a2="$(declare -p array2)"
    
    #combine the two strings trimming where necessary 
    array_both_string="${a1:0:${#a1}-3} ${a2:21}"
    
    # create new associative array from string
    eval "declare -A array_both="${array_both_string#*=}
    
    # show array definition
    for key in ${!array_both[@]}; do
        echo "array_both[${key}]=${array_both[${key}]}"
    done