I made a simple digit counter with associative arrays. Is there a better way to declare and initialize those arrays especially "segments" array to make a 2d array I went with key and value combination. Or this is the only way to do it in Bash?
I would like to hear feedback on the code side too if its not too horrible. It's a simple counter.
#!/bin/bash
#set -x
declare -r MAX_DIGITS=10
declare -i position=0
declare -A digits
declare -A segments
segments["0,0"]=1
segments["0,1"]=1
segments["0,2"]=1
segments["0,3"]=1
segments["0,4"]=1
segments["0,5"]=1
segments["0,6"]=0
segments["1,0"]=0
segments["1,1"]=1
segments["1,2"]=1
segments["1,3"]=0
segments["1,4"]=0
segments["1,5"]=0
segments["1,6"]=0
segments["2,0"]=1
segments["2,1"]=1
segments["2,2"]=0
segments["2,3"]=1
segments["2,4"]=1
segments["2,5"]=0
segments["2,6"]=1
segments["3,0"]=1
segments["3,1"]=1
segments["3,2"]=1
segments["3,3"]=1
segments["3,4"]=0
segments["3,5"]=0
segments["3,6"]=1
segments["4,0"]=0
segments["4,1"]=1
segments["4,2"]=1
segments["4,3"]=0
segments["4,4"]=0
segments["4,5"]=1
segments["4,6"]=1
segments["5,0"]=1
segments["5,1"]=0
segments["5,2"]=1
segments["5,3"]=1
segments["5,4"]=0
segments["5,5"]=1
segments["5,6"]=1
segments["6,0"]=1
segments["6,1"]=0
segments["6,2"]=1
segments["6,3"]=1
segments["6,4"]=1
segments["6,5"]=1
segments["6,6"]=1
segments["7,0"]=1
segments["7,1"]=1
segments["7,2"]=1
segments["7,3"]=0
segments["7,4"]=0
segments["7,5"]=0
segments["7,6"]=0
segments["8,0"]=1
segments["8,1"]=1
segments["8,2"]=1
segments["8,3"]=1
segments["8,4"]=1
segments["8,5"]=1
segments["8,6"]=1
segments["9,0"]=1
segments["9,1"]=1
segments["9,2"]=1
segments["9,3"]=1
segments["9,4"]=0
segments["9,5"]=1
segments["9,6"]=1
declare -A segment_grid
segment_grid["0,0"]=0
segment_grid["0,1"]=1
segment_grid["1,0"]=1
segment_grid["1,1"]=2
segment_grid["2,0"]=2
segment_grid["2,1"]=2
segment_grid["3,0"]=2
segment_grid["3,1"]=1
segment_grid["4,0"]=2
segment_grid["4,1"]=0
segment_grid["5,0"]=1
segment_grid["5,1"]=0
segment_grid["6,0"]=1
segment_grid["6,1"]=1
clear_digits_array() {
local -i i=0
local -i j=0
while [ "$i" -lt 4 ]; do
j=0
while [ "$j" -lt "$((MAX_DIGITS * 4))" ]; do
digits[$i,$j]=' '
((j++))
done
((i++))
done
}
process_digit() {
local -i i=0
local -i row
local -i col
while [ "$i" -lt 7 ]; do
if [ "${segments[$1,$i]}" == 1 ]; then
row="${segment_grid[$i,0]}"
col="${segment_grid[$i,1]}"
col="$((col + $2))"
if [ "$((i % 3))" -eq 0 ]; then
digits[$row,$col]='_'
else
digits[$row,$col]='|'
fi
fi
((i++))
done
}
print_digits_array() {
local -i i=0
local -i j=0
while [ "$i" -lt 3 ]; do
j=0
while [ "$j" -lt "$((MAX_DIGITS * 4))" ]; do
echo -n "${digits[$i,$j]}"
((j++))
done
echo
((i++))
done
}
for number in {0..9}; do
clear
clear_digits_array
process_digit "$number" "$position"
# ((position+=4))
print_digits_array
sleep 0.5
done
exit 0
Initializing indexed arrays is easier than associative arrays. To simplify a bit you could try something like:
declare -a arr=( 1 1 1 1 1 1 0 0 1 1 0 0 0 0 1 1 0 1 1 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 )
declare -A segment
for (( i=0; i<"${#arr[@]}"; i++ )); do
k="$(( i/7 )),$(( i%7 ))"
segment["$k"]="${arr[i]}"
done
But as the index in ${parameter[index]}
is treated as an arithmetic expression you could simply replace your associative array with an indexed array and emulate the 2-dimensions with some arithmetic:
declare -a segment=( 1 1 1 1 1 1 0 0 1 1 0 0 0 0 1 1 0 1 1 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 )
for (( i=0; i<=9; i++ )); do
for (( j=0; j<=6; j++ )); do
printf '%s: %s\n' "$i,$j" "${segment[7*i+j]}"
done
done
0,0: 1
0,1: 1
0,2: 1
...
9,4: 0
9,5: 1
9,6: 1
Note that you could use a string instead of an indexed array because the offset and length in "${parameter:offset:length}"
are also arithmetic expressions:
declare -r segment="1111110011000011011011111001011001110110111011111111000011111111111011"
for (( i=0; i<=9; i++ )); do
for (( j=0; j<=6; j++ )); do
printf '%s: %s\n' "$i,$j" "${segment:7*i+j:1}"
done
done
0,0: 1
0,1: 1
0,2: 1
...
9,4: 0
9,5: 1
9,6: 1