This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
shournk's profile picture

Have a for loop do things in order?

Started by shournk, 29 June 2014 - 01:16 AM
shournk #1
Posted 29 June 2014 - 03:16 AM
I have a monitor to display the status of doors, which is controlled by a different module (connected over networking). I'm using a for loop to grab each door from a table, then draw them consecutively. The problem is, they don't display in order. I'm assuming the reason is because of the nature of for loops and pairs.

The for loop is line 90.

http://pastebin.com/mrgE8u2p

The reason it matters is because the monitor_touch event part needs to associate the location of the touch with an id (which is assumes the table entries are consecutive). I'm also not too good with lua math, but my modulo stuff seems to work.

How do I get the subtables used consecutively? (i.e. the order that the id values are)
Bomb Bloke #2
Posted 29 June 2014 - 03:26 AM
When you stick keys with strings for names into a table, Lua converts those strings to hash values, and indexes your data in memory against those. When you use pairs on the table, you get the values in the order defined by those hashes. This makes it hard to predict what'll come out when.

One way around this is to make another table, filled with numerically indexed values which you could use to get your desired order out of the first table. Eg:

tDoors = { doorA = {...}, doorB = {...}, doorC = {...}, doorD = {...} }

nDoors = {"doorA","doorB","doorC","doorD"}

.
.
.

for i = 1, #nDoors do
	drawEntry(tDoors[ nDoors[i] ].name, tDoors[ nDoors[i] ].state, tDoors[ nDoors[i] ].disabled)
	.
	.
	.
end

But frankly, I'd just use numeric keys all the way:

tDoors = { {...}, {...}, {...}, {...} }

.
.
.

for i = 1, #tDoors do
	drawEntry(tDoors[i].name, tDoors[i].state, tDoors[i].disabled)
	.
	.
	.
end
shournk #3
Posted 29 June 2014 - 03:45 AM
So instead of


local tDoors = {
doorA = {
    id = 1,
    name = "foo",
    state = false,
    disabled = false
    },
doorB = {
    id = 1,
    name = "foo",
    state = false,
    disabled = false
    },
doorC = {
    id = 1,
    name = "foo",
    state = false,
    disabled = false
    }
}

I would use


local tDoors = {
1 = {
    id = 1,
    name = "foo",
    state = false,
    disabled = false
    },
2 = {
    id = 1,
    name = "foo",
    state = false,
    disabled = false
    },
3 = {
    id = 1,
    name = "foo",
    state = false,
    disabled = false
    }
}

Is that right? What does the number sign do?
Lyqyd #4
Posted 29 June 2014 - 04:01 AM
You would either have to put the numbers in square braces, or get rid of them entirely. Declaring the table contents without keys means that they will be automatically assigned numeric keys.
Bomb Bloke #5
Posted 29 June 2014 - 04:04 AM
What does the number sign do?

Do you mean the hash (#)? Sticking it in front of something generally gives you its length.

myTable = {234,23,434,534,42,34}
print( #myTable )  --> 6 entries in the table.

myString = "This is text"
print( #myString ) --> 12 characters in the string.