Page 1 of 1

traverse order of ForEach

Posted: Fri May 12, 2017 1:35 am
by p-OS
I wonder if this is a bug or intentional ?

Program is:

Code: Select all

lov={1,2,3,4,5}

For Local i=0 To ListItems(lov)-1
  DebugPrint("lov[" .. i .. "]=" .. lov[i])
Next

DebugPrint("-------------")

ForEachI(lov,Function(p_index,p_value) DebugPrint("lov[" .. p_index .. "]=" .. p_value) EndFunction)

DebugPrint("-------------")

ForEach(lov,Function(p_index,p_value) DebugPrint("lov[" .. p_index .. "]=" .. p_value) EndFunction)
output is:

Code: Select all

lov[0]=1
lov[1]=2
lov[2]=3
lov[3]=4
lov[4]=5
-------------
lov[0]=1
lov[1]=2
lov[2]=3
lov[3]=4
lov[4]=5
-------------
lov[1]=2
lov[2]=3
lov[3]=4
lov[4]=5
lov[0]=1
While For and ForEachI start with first element in table and stop with last one, ForEach however starts with second element, traverses to last one, and then as last action performs user function on the first element of the table.
Thus one cannot use ForEach if the order of execution is important !

Re: traverse order of ForEach

Posted: Fri May 12, 2017 11:42 am
by SamuraiCrow
It's probably an implementation detail. The table structure is based on a data structure called a hash table. In C++11 it is called an unordered map. It stores key-value pairs but has little concept of what the keys are. It only knows how many pairs are in it and iterates through them once each.

Re: traverse order of ForEach

Posted: Fri May 12, 2017 1:56 pm
by Bugala
Yes, it is intentional. I once asked this same question since i had bug in my code which in the end i found out to be because of this and Andreas basically told what SamuraiCrow just told that basically that command just goes through every item without caring about the order, although in practice it does go them in order but by leaving the first one last.

Re: traverse order of ForEach

Posted: Fri May 12, 2017 6:12 pm
by p-OS
As I frequently read in this forums and couldn't remember any similiar topic I didn't search a lot. But after reading your posts I found quite some threads and the answers there.

It is a known problem and will unlikely change.

Thus I have to use less readable classic FOR statements (with these well known annoying arithemtics cos of the fact that index starts at 0, and resulting bugs) or write my own ForEach replacement.

Re: traverse order of ForEach

Posted: Sun May 14, 2017 7:45 pm
by airsoftsoftwair
It's an implementation detail. The ugliness of index 0 being returned last is due to indices starting at 1 in Lua. In Hollywood, however, indices start at 0 but Lua is optimized for 1-based indices so index 0 is a special case for the VM which is why it is returned after the natural indices of 1,2,3,4,...