2

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.CommentedNov 22, 2015 at 19:26

2 Answers 2

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
    CommentedNov 22, 2015 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?CommentedNov 23, 2015 at 2:13
  • then change while true to ... something else.CommentedNov 23, 2015 at 2:37
  • Well Thank you, and sorry for double askin in stackoverflow, my first day using the sites. Your coding is very good.CommentedNov 23, 2015 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?CommentedNov 23, 2015 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 

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.