2

I am playing a bit with associative arrays in Bash and I found the following difference when declaring the exact same associative array with and without declare. The code is as follows:

#!/usr/bin/env bash

echo -e "\n\nASSOCIATIVE ARRAY\n"
declare -A MY_MAP=( 
    [Madrid]="Spanish" 
    [London]="English" 
    [Paris]="French" 
    [1]=2
    [3]=3.14 
)
echo "First element: $MY_MAP"
echo "Whole content as single string: ${MY_MAP[*]}"
echo "Whole content quoted separately: ${MY_MAP[@]}"
echo "List of indices: ${!MY_MAP[@]}"
echo "Array length: ${#MY_MAP[*]}"
echo "Array length: ${#MY_MAP[@]}"
echo "Second element: ${MY_MAP[London]}"
echo "Last 2 elements: ${MY_MAP[@]:1:3}"

echo -e "\n\nASSOCIATIVE ARRAY - 2\n"
MY_MAP2=( 
    [Madrid]="Spanish" 
    [London]="English" 
    [Paris]="French" 
    [1]=2
    [3]=3.14 
)
echo "First element: $MY_MAP2"
echo "Whole content as single string: ${MY_MAP2[*]}"
echo "Whole content quoted separately: ${MY_MAP2[@]}"
echo "List of indices: ${!MY_MAP2[@]}"
echo "Array length: ${#MY_MAP2[*]}"
echo "Array length: ${#MY_MAP2[@]}"
echo "Second element: ${MY_MAP2[London]}"
echo "Last 2 elements: ${MY_MAP2[@]:1:3}"

When I execute the previous script I do get the following output:

ASSOCIATIVE ARRAY

First element: 
Whole content as single string: French 3.14 2 English Spanish
Whole content quoted separately: French 3.14 2 English Spanish
List of indices: Paris 3 1 London Madrid
Array length: 5
Array length: 5
Second element: English
Last 2 elements: French 3.14 2


ASSOCIATIVE ARRAY - 2

First element: French
Whole content as single string: French 2 3.14
Whole content quoted separately: French 2 3.14
List of indices: 0 1 3
Array length: 3
Array length: 3
Second element: French
Last 2 elements: 2 3.14

My question is what is declare -A doing that makes the output different?

A detailed insight of what is happening here will be appreciated.

Thanks a lot in advance.

1
  • echo is a very poor tool for visualising variables, and particularly arrays. Use declare -p MY_MAP for the whole truth. Also, echo "Last 2 elements: ${MY_MAP2[@]:1:3}" attempts to show three elements, not two: as the elements of an associative array are not ordered, the result is effectively a random choice. Commented May 20, 2023 at 21:39

1 Answer 1

11

declare -A is the only reason your first declaration is treated as an associative array. Your second declaration is handled as an indexed array. When manipulating indexed arrays, indices are treated as arithmetic contexts: Madrid, London, and Paris are interpreted as variable names, and since they hadn’t been declared, their value is 0. As a result, the assignments are read as [0]="Spanish", [0]="English", [0]="French", [1]=2, [3]=3.14, and ${MY_MAP2[London]} is ${MY_MAP2[0]}.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .