【问题标题】:In Lua, how do you find out the key an object is stored in?在 Lua 中,如何找出存储对象的键?
【发布时间】:2012-04-03 00:01:01
【问题描述】:

您将如何 print() 找出或找出对象的索引?

例如,如果我在屏幕上随机生成 20 个岩石对象到一个数组 RockTable = {};

点赞RockTable[#RockTable + 1] = rock;

所有 20 块石头都显示在屏幕上,我如何通过点击它们来找出每块石头的键或索引?

我正在使用 Corona SDK。

任何帮助将不胜感激。

【问题讨论】:

    标签: object lua coronasdk lua-table


    【解决方案1】:

    反转表格:

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

    然后您可以使用倒排表查找索引。

    我发现这个函数非常有用,以至于它进入了我的永久“Lua 实用程序”库。

    【讨论】:

      【解决方案2】:

      还有另一种方法可以做到这一点,即使用元方法。 [已编辑以允许您也删除值]

      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'])
      

      它更加通用,因为您可以复制t 值并随身携带;这也意味着您大部分时间只需要使用一个变量 - 希望可以减少您尝试访问错误内容的可能性。

      【讨论】:

        【解决方案3】:

        最简单的方法是给每块石头添加一个“索引”属性:

        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
        

        如果您使用触摸侦听器方法,您可以通过以下方式检索岩石:

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

        确实,您可以使用索引维护第二张表,但我发现我的方法更简洁 - 当需要删除内容时,您只需要担心一张表,即主表。

        不过我有一个问题:为什么需要检索该索引?在大多数情况下,设计良好的事件监听器函数就足够了,您不需要“找到”您的对象。当然,我缺乏关于您要做什么的信息,但您可能过于复杂了。

        【讨论】:

          【解决方案4】:

          你可以做这样的事情来省去不断循环遍历表以查找索引的麻烦......

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

          那么当你需要知道索引的时候,你可以只用你必须索引RockIndices的rock来快速获取它。如果您“删除”一块岩石,您需要确保在两个位置都将其删除。

          【讨论】:

            【解决方案5】:

            不幸的是,据我所知,您需要对表格进行暴力破解。虽然,要知道一个被点击了,你不需要以某种方式循环它们吗?因此已经知道索引?

            编辑

            哦,除非 Corona 有某种点击回调事件。我从来没有用过它,不过我有 Lua 的经验。

            你也许可以做一个向后参考,像这样:

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

            那么就说rockNum = RocksB[rock]

            我很确定应该可以,但我不能保证,但值得一试。

            编辑2

            蛮力方法看起来有点像:

            function getRock(rock)
                for _,v in pairs(rocks) do
                    if (v == rock)
                        return _
                    end
                end
                return "Rock does not exist."
            end
            

            【讨论】:

            • 如此处所写,RocksRocksB 是相同的数组。您想反转RocksB 中的索引和值,可能是{[a rock]=1,...
            • @RBerteig 哦,是的;我不敢相信我做到了。感谢您指出。
            猜你喜欢
            • 2012-04-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多