2

Simple question: if I have a for loop (zsh) over an unreliable list, by which I mean the list contains entries that can't be predicted beforehand, then can I reset the for loop counter? This demonstrates what I'm asking for:

# e.g. list=(1 5 2 9)
for i in $list ; do
    [[ $i = 2 ]] && i=${list[1]}
done

(This example will obviously loop forever if it worked.)

I can only think of doing it like this:

for ((j=1; j<=${#list}; j++)); do
    [[ ${list[$j]} = 2 ]] && j=1
done

Is there a simpler way of doing it? ("Simpler" meaning easier to follow with the eye what you're doing.)

  • If the list was (1 5 1 2 9), how would zsh know which 1 i=${list[1]} should bring you back to? – Stéphane Chazelas Jul 23 '14 at 15:33
  • Other than the cosmetic replacement to (( list[j] == 2 )) && j=1 or (( list[j] == 2 && j = 1)), I don't think you'll get any much better. – Stéphane Chazelas Jul 23 '14 at 15:36
  • I only need to reset to the beginning of the list, which I should have mentioned. The reset position is not dependent on the contents of list. – Zorawar Jul 23 '14 at 15:39
  • No, I was fearing I would not get any better. I was hoping for some magical builtin command. – Zorawar Jul 23 '14 at 15:41
1

You could do something like:

alias   forever='while ((1))' \
      try-again='continue 2'  \
        ok-done='break'

forever {
  for i ("$list[@]") {
    (( i == 2 )) && try-again
  }
  ok-done
}

Note that you need "$list[@]" instead of $list if you don't want to omit the empty elements.

Not a lot more legible than:

for ((i = 1; i <= $#list; i++)) {
  (( list[i] == 2 )) && i=1
}

though.

  • No, not really, but its an interesting way of doing it that didn't occur to me. – Zorawar Jul 23 '14 at 20:02

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.