1

I am trying to generate a new array, with the combination of other arrays, respecting a specific sequence. In pure Bash. Example:

numbers=(0 1 2 3 4 5 6 7 8);

colors=(red blue green);

loop_sequence=(numbers numbers colors numbers colors colors)

Example output:

0 1 red 2 blue green 3 4 red 5 blue green 6 7 red 8 blue green 0 1 red 2 blue green...

But I find very difficult to make the internal loops of iterations. Any help is very welcome.

1
  • 1
    I wouldn't have bothered answering if I had seen the same question on stackoverflow. Don't post the same question on multiple sites. Nov 22 '15 at 19:26
1

Dynamic variable names are tricky in bash, but do-able with variable indirection.

numbers=(0 1 2 3 4 5 6 7 8)
colors=(red blue green)
loop_sequence=(numbers numbers colors numbers colors colors)

# keep track of where you are in each array
declare -A idx=([numbers]=0 [colors]=0)

for varname in "${loop_sequence[@]}"; do 
    tmp="${varname}[${idx[$varname]}]"   # construct the array reference
    echo "$varname => ${!tmp}"           # variable indirection gets the value
    (( idx[$varname]++ ))
done

outputs

numbers => 0
numbers => 1
colors => red
numbers => 2
colors => blue
colors => green

To indefinitely repeat the loop_sequence, you can:

declare -A idx=([numbers]=0 [colors]=0)
# store the array sizes for convenience
declare -A size=([numbers]=${#numbers[@]} [colors]=${#colors[@]})
while true; do 
    for varname in "${loop_sequence[@]}"; do 
        tmp="${varname}[${idx[$varname]}]"
        echo "$varname => ${!tmp}"
        # loop the array index
        (( idx[$varname] = (idx[$varname]+1) % size[$varname] ))
    done
done | less
7
  • that's a pretty neat trick.
    – mikeserv
    Nov 22 '15 at 21:59
  • what if the loop sequence should be the lengh to cover the full iteration of the longest array, while the shorter array iteration loop to prevent blank strings outputs and the break of the sequence?
    – nagualcode
    Nov 23 '15 at 2:13
  • then change while true to ... something else. Nov 23 '15 at 2:37
  • Well Thank you, and sorry for double askin in stackoverflow, my first day using the sites. Your coding is very good.
    – nagualcode
    Nov 23 '15 at 14:06
  • Can I use this code for, 3, 4 or more arrays combinations, named in the 'loop_sequence' array? Then I would just need to add then to the declare -A line too?
    – nagualcode
    Nov 23 '15 at 14:08
0
x=$(( (l=${#loop_sequence[@]}) * (n=${#numbers[@]}) * (c=${#colors[@]})))
_n= _c= _l=
set --    
math(){ return "$(($1-=-($1<${1#?})|$1-1))"; }
while   [ "$((x-=1))" -ge 0 ]
do      math _l
        case "${loop_sequence[$?-1]}" in
        n*)  math _n
             set -- "$@" "${numbers[$?-1]}";;
        *)   math _c
             set -- "$@" "${colors[$?-1]}";;
        esac
done;   printf %s\\n  "$@"

0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.