# How to both get the original and reverse order of an array?

So, Let's say i have an array `arr`, with two element in it:

``````read -a arr <<< "\$@"
``````

where i would then either use it in a function or script and input two string or element like so:

``````read_me() {
read -a arr <<< "\$@"
}
read_me "first test"
``````

Now i already know how to get through all the elements of an array:

``````for i in "\${arr[@]}"
do
echo "\$i" # where i do something with the respective element of said array.
done
``````

But that only do it using the normal/original order in which the element were added to the previously mentioned array... Of course, i also know how to get the elements of an array in reverse order:

``````indices=( \${!arr[@]} )
for ((i=\${#indices[@]} - 1; i >= 0; i--)) ; do
echo "\${arr[indices[i]]}"
done
``````

Both of these ways work as intended. Problem though, is that i need both the normal and the reverse order on the same loop. Mostly so i wouldn't need to do this:

``````echo "\${arr[0]}" "\${arr[1]}"
echo "\${arr[1]}" "\${arr[0]}"
``````

How could i do this in a single loop?

• Given that the array only contains two elements, I'm not even sure why there needs to be an array, or why the last piece of code is not good enough. Apr 25, 2021 at 20:29
• Because if i were to add more elements to previously mentioned array, then the last piece of code would need to be later expanded :) @Kusalananda which is why I'm trying to make a loop (single loop encompassing what i already know how to do) Apr 25, 2021 at 20:30

## 1 Answer

``````array=( 1 2 3 a b c )

for i in "\${!array[@]}"; do
j=\$(( \${#array[@]} - i - 1 ))
printf '%s\t%s\n' "\${array[i]}" "\${array[j]}"
done
``````

Output:

``````1       c
2       b
3       a
a       3
b       2
c       1
``````

In short, there is nothing stopping you from traversing the array in any order and at the same time calculate a new index from the current index and use that too.

In comments to the question, there is a suggestion for the following arithmetic loop:

``````for (( i = 0, j = \${#array[@]} - 1; i < \${#array[@]}; ++i, --j ))
do
printf '%s\t%s\n' "\${array[i]}" "\${array[j]}"
done
``````

This uses the fact that the comma operator can be used in the initialization and update parts of the loop header to maintain two separate loop variables.

Depending on what you want to achieve and depending on what your actual array values are, you may also get away with using `tac`:

``````\$ paste <( printf '%s\n' "\${array[@]}" ) <( printf '%s\n' "\${array[@]}" | tac )
1       c
2       b
3       a
a       3
b       2
c       1
``````
• Yeah, this look much better than what i had in mind (which was two `for loop`). Thanks a lot :) Apr 25, 2021 at 20:40