user3713179
user3713179

Reputation: 361

Return table value index via metatable

I'm looking for a way to retrive index value via metatable. This is my attempt:

local mt = { __index =
   {          
      index = function(t, value)
         local value = 0
         for k, entry in ipairs(t) do                
            if (entry == value) then 
               value = k
            end
         end
         return value
      end          
   }
}

t = {
    "foo", "bar"
}

setmetatable(t,mt)

print(t.index(t,"foo"))

Result is 0 instead of 1. Where I'm wrong?

Upvotes: 1

Views: 163

Answers (2)

Luatic
Luatic

Reputation: 11201

Result is 0 instead of 1. Where [am I] wrong?

The code for the index function is wrong; the problem is not related to the (correct) metatable usage. You're shadowing the parameter value when you declare local value = 0. Subsequent entry == value comparisons yield false as the strings don't equal 0. Rename either the parameter or the local variable:

index = function(t, value)
    local res = 0
    for k, entry in ipairs(t) do                
        if entry == value then 
            res = k
        end
    end
    return res
end

An early return instead of using a local variable in the first place works as well and helps improve performance.

To prevent such errors from happening again, consider getting a linter like Luacheck, which will warn you if you shadow variables. Some editors support Luacheck out of the box; otherwise there are usually decent plugins available.

Upvotes: 1

Reinisdm
Reinisdm

Reputation: 126

My attempt:

local mt = {
    __index = function(t,value)
        for index, val in pairs(t) do
            if value == val then
                return index
            end
        end
    end
}

t = {
   "foo",
   "bar",
   "aaa",
   "bbb",
   "aaa"
}

setmetatable(t,mt)


print(t["aaa"]) -- 3
print(t["asd"]) -- nil
print(t["bbb"]) -- 4
print(t["aaa"]) -- 3
print(t["bar"]) -- 2
print(t["foo"]) -- 1

Upvotes: 1

Related Questions