Magicked
Magicked

Reputation: 647

How do I iterate through this table?

I have the following table:

self.keytable = {}
self.keytable.rotate_right = false
self.keytable.rotate_left = false
self.keytable.thrust = false
self.keytable.brake = false
self.keytable.fire = false

I want to iterate through the table and set each value to false, but I must be missing some nuance of Lua. I've tried the following without luck:

for k,v in ipairs(self.keytable) do
    v = false
end

Thanks in advance for any help!

Upvotes: 0

Views: 589

Answers (3)

catwell
catwell

Reputation: 7048

The two other answers are both right.

1) ipairs iterates over integer keys (and you should just forget about it anyway, it is not better than the numeric for loop). Here you keys are strings so you must use pairs. Here's your example rewritten with it:

for k,v in pairs(self.keytable) do
  v = false
end

2) This still does not work because of the reason given by Mud: v is local to the loop. Actually you do not need it at all, here is a correct version:

for k in pairs(self.keytable) do
  self.keytable[k] = false
end

Upvotes: 1

Mud
Mud

Reputation: 28991

I want to iterate through the table and set each value to false, but I must be missing some nuance of Lua. I've tried the following without luck:

for k,v in ipairs(self.keytable) do  
    v = false  
end  

Is it easier to see why this wouldn't work?

local v = self.keytable[rotate_right]
v = false

You copy the value of self.keytable[rotate_right] into v. Subsequently writing a different value to v doesn't affect the value in keytable.

This is exactly what's happening in the for loop, which is equivalent to this:

for k=1,#self.keytable do
    local v = self.keytable[k]
    v = false
end

If you want to update the value in keytable you need to write:

for k=1,#self.keytable do
    self.keytable[k] = false
end

Or, if you're using ipairs (as in your original loop):

for k,v in ipairs(self.keytable) do
    self.keytable[k] = false
end

Upvotes: 5

Mike Corcoran
Mike Corcoran

Reputation: 14565

i'm not exactly sure what your intent is here, but when working with non-integer keys you must use the pairs() built-in function. ipairs() is only to iterate tables with numeric keys, and in the example above you're assigning false to non-numeric keys in keytable.

if you want to avoid having to set each key in keytable to false like you did in your code example, something like this would do what you want a little cleaner:

local keytable = {}
local keys = {"rotate_right", "rotate_left", "thrust", "brake", "fire"}

for _,key in pairs(keys) do
    keytable[key] = false
end

this produces this output when printed:

thrust  false
brake   false
fire    false
rotate_left false
rotate_right    false

the code above just iterates over string values, and then sets them as the keys to keytable while assigning them the value false.

Upvotes: 2

Related Questions