Arrays are variables that can hold multiple values. You can thinks arrays as a way to group variables instead of creating a new variable everytime needed. Usually these values are the same type, but in the shell script these values may be the same type or different type because at the end everything in a shell script is treated as a string.
There are two types of arrays in bash: indexed and associative. This chapter focuses mainly on the one-dimensional indexed arrays that are usually called as a ordered lists. This means that every value has it's own index number associated with.


Declare an array

Indexed arrays can be created by using compound assignment () or by using a built-in command declare. Note that declare command can be also used to create a associative arrays!

Creating an indexed array:

#!/bin/bash

#new indexed array defination with a population
ARRAY1=(value1 value2 value3)

#new indexed array defination with a declare builtin command and manual value assignment
declare -a ARRAY2
ARRAY2[0]="value1"
ARRAY2[1]="value2"

#save the command stdout to an array (command substitution)
ARRAY3=( $(ls) )

Creating an associative array (dictionary):

#!/bin/bash

#defining a new associative array with a declare buildin command
#Note a different argument (-A)!

declare -A ARRAY1
ARRAY1[a]=123
ARRAY1[b]=987

Array operations

After the array is created, operations can be performed to it. In the following examples, index can be replaced with a key value.

Get a desired item value.
Syntax: ${ARRAYNAME[<index>]} or "${ARRAYNAME[<index>]}"

Get all the array values:
Syntax 1: ${ARRAYNAME[@]} or ${ARRAYNAME[*]}
Syntax 2: $"{ARRAYNAME[@]}" or "${ARRAYNAME[*]}"

Get all the indexes/keys:
Syntax: ${!ARRAYNAME[@]}

Get the size of an array:
Syntax: ${#ARRAYNAME[@]}

Get the size of a particular item:
Syntax: ${#ARRAYNAME[index]}

Overwrite the existing item value:
Syntax: ARRAYNAME[index]="value"

Append values at the end of the array:
Syntax: ARRAYNAME+=("value")

Save the command output as an array:
Syntax: ARRAYNAME=( $(ls /) )

Delete item:
Syntax: unset ARRAYNAME[index]

Delete array:
Syntax: unset ARRAYNAME

NOTE!
When you are getting all the values from the array (${ARRAYNAME[@]}), if the syntax is not wrapped in double quotes, array is exposed to word splitting (spaces inside string, default IFS)! Same principle applies when you are iterating a single item from the array (${ARRAYNAME[index]}).
There is also a difference between @ and * characters when using quotes:
"${ARRAYNAME[*]}" evaluates to every element of the array as a single word.
"${ARRAYNAME[@]}" evaluates to every element of the array, as a separate words.


Iterating an array

The following example shows how to print all the values on indexed and associative array:

#!/bin/bash

ARRAY1=("dog" "cat" "whale" "pig" "horse")
for value in ${ARRAY1[@]}
do
  echo ${value}
done

#-------------------------------------

declare -A ARRAY2
ARRAY2[a]="dog"
ARRAY2[b]="cat"

for value in ${ARRAY2[@]}
do
  echo ${value}
done

The following example demonstrates the differences while using quotes while getting all values:

#!/bin/bash

ARRAY1=("im a dog" "im a cat" "whale swims")
for value in ${ARRAY1[@]}
do
  echo ${value}
done

#returns:
#im
#a
#dog
#im
#a
#cat
#whale
#swims

#-------------------------------------

#With quotes
#!/bin/bash

ARRAY1=("im a dog" "im a cat" "whale swims")
for value in "${ARRAY1[@]}"
do
  echo ${value}
done

#returns:
#im a dog
#im a cat
#whale swims

#-------------------------------------

#With quotes and asterisk
#!/bin/bash

ARRAY1=("im a dog" "im a cat" "whale swims")
for value in "${ARRAY1[*]}"
do
  echo ${value}
done

#returns:
#im a dog im a cat whale swims

If you want to also get index numbers/key values?

#!/bin/bash

ARRAY1=("dog" "cat" "whale" "pig" "horse")

for key in ${!ARRAY1[@]}
do
  echo "key: ${key}, value: ${ARRAY1[$key]}"
done

#-------------------------------------

declare -A ARRAY2
ARRAY2[a]="dog"
ARRAY2[b]="cat"

for key in ${!ARRAY2[@]}
do
  echo "key: ${key}, value: ${ARRAY2[$key]}"
done