[Solved] Wildcard index for a table

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
PiFace
Prole
Posts: 28
Joined: Mon Sep 05, 2016 5:35 pm
Location: Brazil

[Solved] Wildcard index for a table

Post by PiFace »

I got this problem while trying to make a placeholder/wildcard index for a table. Example: there's a table called t, with keys 1,3,9,13,100 (any number could be used) storing some value, but then I try to work with a value that was supposed to be on key 99. Of course t[99] will be nil, right? But as that kind of situation could happen any time, I need a placeholder value, preferably inside that same table, with a key that would not be used during the game (0, for example, or "placeholder", doesnt matter). What is the right approach for this? I've been trying to use the __index metamethod but errors wont stop popping, either stack overflow happens, or the table always uses the placeholder even when the value in a key is not nil.

TL;DR: how do I redirect a key with nil value in a table to a key with a placeholder value?

(I'm on the phone now, so I'll post a snippet later if needed)
Last edited by PiFace on Tue Nov 01, 2016 1:13 am, edited 1 time in total.
User avatar
pgimeno
Party member
Posts: 3674
Joined: Sun Oct 18, 2015 2:58 pm

Re: Wildcard index for a table

Post by pgimeno »

Do you mean a default value? Like "if the index doesn't exist then return this"?

If so, it's simple:

Code: Select all

setmetatable(yourtable, {__index = function() return default_value end})
Example:

Code: Select all

yourtable = {[1] = "pineapple", [3] = "banana", [9] = "mango", [13] = "eggplant", [100] = "brocoli"}
local default_value = "orange"
setmetatable(yourtable, {__index = function() return default_value end})
print(yourtable[100]) -- prints "brocoli"
print(yourtable[99]) -- prints "orange"
User avatar
sherpal
Prole
Posts: 17
Joined: Wed Sep 14, 2016 9:29 am
Location: Belgium

Re: Wildcard index for a table

Post by sherpal »

Using the __index metamethod is the right thing to do. Consider the following example:

Code: Select all

a = {
  __index = function(tab, key)
    return a.prototype
  end,
  prototype = 'this is the prototype value',
}

a[1] = 2
a.hello = 'hi'

setmetatable(a,a)

print(a[2])
print(a[1])
print(a.is_this_defined)
print(a.hello)
The __index method is called each time the field of a you're trying to access is nil.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Wildcard index for a table

Post by kikito »

You can also use "or <default value>". Like so:

Code: Select all

local tbl = {a=1}

print(tbl['a'] or 0) -- 1
print(tbl['b'] or 0) -- 0
When I write def I mean function.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Wildcard index for a table

Post by raidho36 »

That's preferable even, since if table returns default value if key doesn't exist, there's no way to tell if any element is having default value or doesn't exist.
User avatar
PiFace
Prole
Posts: 28
Joined: Mon Sep 05, 2016 5:35 pm
Location: Brazil

Re: Wildcard index for a table

Post by PiFace »

Thank you guys! __index should have done the work a loong time ago, but I just forgot that there was a function somewhere else that was doing the following:
- it checked if the key held an image, if it did, it just skipped everything so it wouldn't load it again
- if it was nil, then it loaded a new image

But with __index it would always be different to nil, so no new images would be loaded, but I fixed that by checking if table[key]==table[0] (the key 0 was the default value)
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: [Solved] Wildcard index for a table

Post by raidho36 »

Or you could just check if it was nil, without doing everything else.
User avatar
PiFace
Prole
Posts: 28
Joined: Mon Sep 05, 2016 5:35 pm
Location: Brazil

Re: [Solved] Wildcard index for a table

Post by PiFace »

raidho36 wrote:Or you could just check if it was nil, without doing everything else.
I was actually doing that before, but that table is called in many different parts of the code, and I could use it elsewhere too, so it's more practical to use __index to avoid checking nil everytime I had to use the table. Checking nil would have to be there all the time, whereas with __index I have to check the default value only in 1 function.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: [Solved] Wildcard index for a table

Post by raidho36 »

But you didn't gain anything by that - if index metamethod is set, then it checks if value is nil and invokes the index.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: [Solved] Wildcard index for a table

Post by Nixola »

But if the default value changes, it's one place to change instead of several scattered through the code.
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 9 guests