'Lua - Creating a lookup table that handles a nil value?
I have one Lua table that I want to use as a look up for another table, and while I can get it to work when there is a matching ID/key, I can’t make handle blanks (entries with no key to map.)
To explain what I mean, I create the follow room number/ID to room name table this way..
local room_index = {}
for i,n in pairs (luup.rooms) do
room_index[i] = n
end
Which creates the following..
{ [1]="Kitchen", [2]="Outside", [3]="Living Room", [4]="Front Room", [5]="Office", [6]="Hallway", [7]="Conservatory", [8]="Landing", [9]="Emma's Room", [10]="Lean To", [11]="Back Landing", [12]="Front Landing", [13]="Boiler Room", [14]="Loft Landing", [15]="Ben's Room", [16]="Main Bedroom", [17]="Under Stairs" }
I then I look to the a devices table to show which device is in which room.
for i,d in pairs(luup.devices) do
local r = d.room_num
print(room_index[r], d.description)
end
Which creates the following ..
Office ZRC-90U Controller
Kitchen TKB Energy
nil Home Energy Meter Gen5
nil Clamp 1
Living Room Living Room Media
nil WWN Home/Away - Home
Under Stairs Under Stairs Temp
Under Stairs Under Stairs Power
Living Room TV Headphones
The problem I have is that I can’t work out how to handle the nil values, where there is not an Room number/ID associated with the device, how do I handle this? Rather than nil, I’d just like it to say "No Room"
I looked at various other SO posts, which seem quite complex. Surely this is something relatively straight forward when doing look up tables ? It’s like I need a default [nil]="No Room" entry somewhere?
Solution 1:[1]
If you really want your table to return "No Room" when indexed with nil, you can implement that using a metatable:
setmetatable(room_index, {__index = function(self, key)
if key == nil then return "No Room" end
end})
Be warned that this may increase the error-proneness of your application: Something like room_index[uninitialized_variable] will return "No Room" as well.
Solution 2:[2]
While it is possible to index a table with nil (see the other answer), I don't think it's the best solution to the issue, or a clean solution at all. Lua uses nil in a few special places when iterating through a table, and using it for something meaningful is counterintuitive.
If all you want is to be able to turn nil into a custom text, you don't have to use a metatable for that; use a function:
function room_name(index)
if index then
return room_index[index]
end
return "No Room"
end
Or, if it could make sense to represent a "No Room" entity as an actual entity, for other purposes, just use a non-nil value:
local no_room = -1
room_index[no_room] = "No Room"
for i,d in pairs(luup.devices) do
local r = d.room_num
print(room_index[r or no_room], d.description)
end
Or, if you cannot assume that -1 be an invalid index, use a string or {} to index it; it's all the same to Lua.
Solution 3:[3]
In this particular situation the table I was doing the look ups from, stored devices with no room associated with a 0 (zero), so in the end I could use that.
local room_index = {}
for i,n in pairs (luup.rooms) do
room_index[i] = n
end
print (pretty(room_index))
for i,d in pairs(luup.devices) do
local r = d.room_num
if r ~= 0 then print(room_index[r], d.description)
else print ("No Room", d.description)
end
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | LMD |
| Solution 2 | IS4 |
| Solution 3 |
