Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an associative array as argument to a function in Bash?

How do you pass an associative array as an argument to a function? Is this possible in Bash?

The code below is not working as expected:

function iterateArray {     local ADATA="${@}"            # associative array  for key in "${!ADATA[@]}" do     echo "key - ${key}"     echo "value: ${ADATA[$key]}"  done  } 

Passing associative arrays to a function like normal arrays does not work:

iterateArray "$A_DATA" 

or

iterateArray "$A_DATA[@]" 
like image 296
niksfirefly Avatar asked Nov 01 '10 13:11

niksfirefly


People also ask

How do you pass an associative array to a function?

You can only pass associative arrays by name. It's better (more efficient) to pass regular arrays by name also. You would do something like eval echo "\${$1[$key]}" in the function, and pass in the name of the variable, without the $ .

Does bash have associative arrays?

Bash, however, includes the ability to create associative arrays, and it treats these arrays the same as any other array. An associative array lets you create lists of key and value pairs, instead of just numbered values.


2 Answers

I had exactly the same problem last week and thought about it for quite a while.

It seems, that associative arrays can't be serialized or copied. There's a good Bash FAQ entry to associative arrays which explains them in detail. The last section gave me the following idea which works for me:

function print_array {     # eval string into a new associative array     eval "declare -A func_assoc_array="${1#*=}     # proof that array was successfully created     declare -p func_assoc_array }  # declare an associative array declare -A assoc_array=(["key1"]="value1" ["key2"]="value2") # show associative array definition declare -p assoc_array  # pass associative array in string form to function print_array "$(declare -p assoc_array)"  
like image 140
Florian Feldhaus Avatar answered Oct 07 '22 02:10

Florian Feldhaus


If you're using Bash 4.3 or newer, the cleanest way is to pass the associative array by name and then access it inside your function using a name reference with local -n. For example:

function foo {     local -n data_ref=$1     echo ${data_ref[a]} ${data_ref[b]} }  declare -A data data[a]="Fred Flintstone" data[b]="Barney Rubble" foo data 

You don't have to use the _ref suffix; that's just what I picked here. You can call the reference anything you want so long as it's different from the original variable name (otherwise youll get a "circular name reference" error).

like image 20
Todd Lehman Avatar answered Oct 07 '22 01:10

Todd Lehman