Associative arrays (Bash)
- Associative arrays are arrays where you can give elements their own name
- You can use associative arrays to mimic multi-dimensional arrays, with emphasize on mimic
- Associative arrays are new in Bash 4. To verify which version of Bash you have:
bash --version
An associative array means, that the index doesn't have to be a number, but can be symbolic, or a key. E.g.:
declare -A j j[fruit]=apple j[color]=blue
Mimicing multidimensional arrays
Associative arrays aren't really multidimensional arrays, but they can mimic them:
unset j declare -A j j[0,0]="00" j[0,1]="01" j[0, 1]="0 1" for i in "${!j[@]}" do echo "Index: $i - Value: ${j[$i]}" done
Output:
Index: 0, 1 - Value: 0 1 Index: 0,1 - Value: 01 Index: 0,0 - Value: 00
So, the entry with index [0, 1]
, is not the same as with index [0,1]
.
On the other hand: Does it actually matter? You can use variables for these indices. And I don't really need to make calculations concerning different dimensions.
Numerical index
Example:
declare -A arr arr[0,0,0]="000" arr[0,0,1]="001" arr[0,1,0]="010" arr[0,1,1]="011" arr[1,0,0]="100" arr[1,0,1]="101" arr[1,1,0]="110" arr[1,1,1]="111" echo "${arr[0,0,0]} ${arr[0,0,1]} ${arr[0,1,0]} ${arr[0,1,1]}" echo "${arr[1,0,0]} ${arr[1,0,1]} ${arr[1,1,0]} ${arr[1,1,1]}"
Symbolic index
A symbolic index is probably the same as an associative index: Referring to a cell through an association, not a number.
An example to rule 'm all:
unset j declare -A j j[fruit,one]=Mango j[fruit,two]=Apple j[bird,1]=Cockatail j[bird,2]=Spottingbird j[flower,1]=Rose j[flower,2]=Sunflower j[animal]=Tiger for i in "${j[@]}" do echo "Entry: $i" done
Output:
Entry: Cockatail Entry: Spottingbird Entry: Rose Entry: Sunflower Entry: Tiger Entry: Apple Entry: Mango
Note:
- The entries seem to appear in arbitrary order
- The first two entries have two indices that are both symbolic
- The last item only has one index. That's not a problem
- No problem to loop over a multidimensional symbolic array like this :)
Loop through an associative onedimensional array
This works [1]:
declare -A assArray1 assArray1[fruit]=Mango assArray1[bird]=Cockatail assArray1[flower]=Rose assArray1[animal]=Tiger for i in "${assArray1[@]}" do echo " Entry: $i" done
Output:
Entry: Mango Entry: Rose Entry: Tiger Entry: Cockatail
Loop through a multidimensional array
This works:
declare -A assArray1 assArray1[fruit,1]=Mango assArray1[fruit,2]=Apple assArray1[bird,1]=Cockatail assArray1[bird,2]=Spottingbird assArray1[flower,1]=Rose assArray1[flower,2]=Sunflower assArray1[animal,1]=Tiger assArray1[animal,1]=Mouse for i in "${assArray1[@]}" do echo " Entry: $i" done
Output:
Entry: Cockatail Entry: Spottingbird Entry: Rose Entry: Sunflower Entry: Mouse Entry: Mango Entry: Apple
The only problem: The entries seem to be quite random. This is also the case if I insert statement unset assArray1
at the beginning of the script.
Looping through the rows of an associate array: This one isn't as cool as the code before, because the index is given explicitly:
i=1 for ((i; i<=$number_of_sites; i++)) do echo "Row ${i}: ${site[$i,1]} & ${site[$i,2]}" done
Loop through the index of a multidimensional array
This works:
declare -A assArray1 assArray1[fruit,1]=Mango assArray1[fruit,2]=Apple assArray1[bird,1]=Cockatail assArray1[bird,2]=Spottingbird assArray1[flower,1]=Rose assArray1[flower,2]=Sunflower assArray1[animal,1]=Tiger assArray1[animal,1]=Mouse for i in "${!assArray1[@]}" do echo "Index: $i" done
With output:
Index: bird,1 Index: bird,2 Index: flower,1 Index: flower,2 Index: animal,1 Index: fruit,1 Index: fruit,2
However, this is totally not exciting: The index was explicitly specified when initialising the array. That's different when you initialise an array through e.g., i= ( 1 2 3 blub 5 )
(or whatever the exact syntax is).
Index + value
Again, not very exciting, but maybe instructive at times:
unset j declare -A j j[fruit,one]=Mango j[fruit,two]=Apple j[bird,1]=Cockatail j[bird,2]=Spottingbird j[flower,1]=Rose j[flower,2]=Sunflower j[animal]=Tiger for i in "${!j[@]}" do echo "Index: $i - Value: ${j[$i]}" done
Output:
Index: bird,1 - Value: Cockatail Index: bird,2 - Value: Spottingbird Index: flower,1 - Value: Rose Index: flower,2 - Value: Sunflower Index: animal - Value: Tiger Index: fruit,two - Value: Apple Index: fruit,one - Value: Mango
Awk
And for something entirely else: I kinda moved from a spreadsheet to associative arrays. A while ago I saw on YouTube Gary Explains: EVERYONE Needs to Learn a Little Bit of AWK! - Maybe this is what I need?