In Lua, how do you find out the key an object is stored in?

后端 未结 5 766
失恋的感觉
失恋的感觉 2020-12-21 07:59

How would you print() out or find out the index of an object?

For example, if I spawned 20 random rock objects on screen into an array RockTable = {};<

相关标签:
5条回答
  • 2020-12-21 08:54

    Invert the table:

    function table_invert(t)
      local u = { }
      for k, v in pairs(t) do u[v] = k end
      return u
    end
    

    You can then use the inverted table to find the index.

    I find this function so useful that it goes into my permanent "Lua utilities" libraries.

    0 讨论(0)
  • 2020-12-21 08:54

    The simplest way is to add an "index" property to each rock:

    RockTable = {}
    
    for i=1,20 do
    
        local rock
        -- do your thing that generates a new 'rock' object
    
        rock.index = #RockTable + 1
        RockTable[rock.index] = rock
    
    end
    

    If you use a touch listener method, you can retrieve the rock this way:

    function touchListener( event )
        local rock = event.target
        local rockIndex = rock.index
        -- ...
    end
    

    It is true that you can maintain a second table with indices, but I find my method cleaner - when it is time to remove things, you only have to worry about one table, the main one.

    I have a question though: why do you need to retrieve that index? In most cases, well designed event listener functions are enough, you don't need to "find" your objects. Of course I lack information on what you are trying to do, but it is possible that you are over-complicating things.

    0 讨论(0)
  • 2020-12-21 08:57

    you could do something like this to save you some trouble of constantly looping over a table to find the index...

    RockTable = {}
    RockIndicies = {}
    
    for i = 1, 20 do
        idx = #RockTable + 1
        RockTable[idx] = rock
        RockIndicies[rock] = idx
    end
    

    then when you need to know the index, you can just use the rock you have to index RockIndices to quickly get it. If you 'delete' a rock, you'd want to make sure to remove it in both places.

    0 讨论(0)
  • 2020-12-21 08:59

    Unfortunately you'd need to brute the table, to my knowledge. Although, to know that one was clicked, wouldn't you need to be looping them in some way anyway; and therefore already know the index?

    Edit

    Oh, unless Corona has some sort of callback event for clicking. I've never used it, I've got experience in Lua though.

    You could maybe do a backwards reference, like so:

    Rocks = {a rock, a rockB, a rockC}
    RocksB = {[a rock] = 1, [a rockB] = 2, [a rockC] = 3}
    

    Then just say rockNum = RocksB[rock]

    I'm pretty certain that should work but I can't guarantee it, worth a try though.

    Edit2

    The brute method would look somewhat like:

    function getRock(rock)
        for _,v in pairs(rocks) do
            if (v == rock)
                return _
            end
        end
        return "Rock does not exist."
    end
    
    0 讨论(0)
  • 2020-12-21 09:01

    There's another way you can do it, using metamethods. [Edited to allow you to remove values too]

    t = {} -- Create your table, can be called anything
    t.r_index = {} -- Holds the number value, i.e. t[1] = 'Foo'
    t.r_table = {} -- Holds the string value, i.e. t['Foo'] = 1
    
    mt = {} -- Create the metatable
    mt.__newindex = function (self, key, value) -- For creating the new indexes
        if value == nil then -- If you're trying to delete an entry then
            if tonumber(key) then -- Check if you are giving a numerical index
                local i_value = self.r_index[key] -- get the corrosponding string index
                self.r_index[key] = nil -- Delete
                self.r_table[i_value] = nil
            else -- Otherwise do the same as above, but for a given string index
                local t_value = self.r_table[key]
                self.r_index[t_value] = nil
                self.r_table[key] = nil
            end
        else
            table.insert(self.r_index, tonumber(key), value) -- For t[1] = 'Foo'
            self.r_table[value] = key -- For t['Foo'] = 1
        end
    end
    mt.__index = function (self, key) -- Gives you the values back when you index them
        if tonumber(key) then
            return (self.r_index[key]) -- For For t[1] = 'Foo'
        else
            return (self.r_table[key]) -- For t['Foo'] = 1
        end
    end
    
    setmetatable(t, mt) -- Creates the metatable
    
    t[1] = "Rock1" -- Set the values
    t[2] = "Rock2"
    
    print(t[1], t[2]) -- And *should* proove that it works
    print(t['Rock1'], t['Rock2'])
    
    t[1] = nil
    print(t[1], t[2]) -- And *should* proove that it works
    print(t['Rock1'], t['Rock2'])
    

    It's more versatile as you can copy the t value and take it with you; it also means that you only have to play around with the one variable most of the time - hopefully should reduce the likelihood of you trying to access the wrong thing.

    0 讨论(0)
提交回复
热议问题