For each index & value loop.
Description
Having talked with Ayham about my concerns, I've opened this as an alternative proposal to Ayham's loop PR #6053.
This will be in draft until we reach a consensus about which approach to adopt.
Ayham's syntax was:
loop %objects% with index as %-~object%
loop %objects% [with index] as %-~object%( and|,) [with value] %-~object%
loop %objects% [[with value] as %-~object%]
I'm not very happy about changing or adding to the existing loop ... section syntax, because it's such an old and established thing, and I worried that the syntax was becoming a bit long and difficult to interpret.
I also thought this feature might be a good opportunity to mimic for-each loops from other languages like Java and Python.
My alternative for-each is specifically designed for dealing with key<->value maps, by storing the index and value in reference variables.
It also extends the existing SecLoop so all loop behaviour is available as normal.
The syntax is (note ~object specifically accepts a variable):
for [each] [value] %~object% in %objects%
for [each] (key|index) %~object% in %objects%
for [each] [key|index] %~object% (=|and) [value] %~object% in %objects%
Note: while I wanted to do for A, B in ... (like Python) I was concerned that Skript might mistake this for for <list of A, B> in ... rather than for <A>, <B> in ....
set {_list::*} to 1, 5, and 10
# loop-by-value like a regular loop
for each {_value} in {_list::*}:
broadcast {_value}
for value {_value} in {_list::*}:
broadcast {_value}
# loop-by-index
for index {_index} in {_list::*}:
broadcast {_index}
# loop by index = value
for index {_index} and value {_value} in {_list::*}:
broadcast "%{_index}% = %{_value}%"
for {_index} and {_value} in {_list::*}:
broadcast "%{_index}% = %{_value}%"
for {_index} = {_value} in {_list::*}:
broadcast "%{_index}% = %{_value}%"
Note: this is registered as an experimental feature, toggled with using for each loops.
Target Minecraft Versions: any Requirements: #6551, #6552 Related Issues: #6052, #6053
I'm still not sure about this feature. I think the existing system works well, and I think there's a benefit in just having a single simple way to loop things.
I'm still not sure about this feature. I think the existing system works well, and I think there's a benefit in just having a single simple way to loop things.
I'm happy with that too, but if people decide we need something I am in favour of this being it.
Pretty much every loop I've written recently has looked like this, when more than one nested loop is involved.
loop 10 times:
set {_counter} to loop-value
loop {_something::*}:
set {_value} to loop-value-2
It's just so much easier to keep track of what's what, helps avoid off-by-one errors in the loop-value-x, and being able to have descriptive names makes the code way more legible. That said, this code is perfectly fine to keep, but I feel like this addition would be valuable in that it would remove the dead weight of those set lines.
helps avoid off-by-one errors in the loop-value-x
I have a vague memory that there are some cases where you can't use the loop-<something>-x because it isn't available within some kinds of subsections (or something like that) and you have to copy it to a variable too.
helps avoid off-by-one errors in the loop-value-x
I have a vague memory that there are some cases where you can't use the
loop-<something>-xbecause it isn't available within some kinds of subsections (or something like that) and you have to copy it to a variable too.
Yes, any section that resets the events (EffSecSpawn, for example) means you have to put the loop-value into a var in order to access it in the section, since when it runs isn't guaranteed.
We voted for Sovde's suggestion to go with this version but allow loop as an alternative to for (each).