В Lua, как вы узнаете ключ, в котором хранится объект? - PullRequest
3 голосов
/ 18 марта 2012

Как бы вы распечатать () или узнать индекс объекта?

Например, если я породил 20 случайных каменных объектов на экране в массив RockTable = {};

Как это RockTable[#RockTable + 1] = rock;

И все 20 камней отображаются на экране какмогу ли я узнать, какой ключ или индекс есть у каждого камня, нажав на них?

Я использую Corona SDK.

Любая помощь будет принята с благодарностью.

Ответы [ 5 ]

4 голосов
/ 19 марта 2012

Инвертировать таблицу:

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

Затем вы можете использовать перевернутую таблицу, чтобы найти индекс.

Я считаю эту функцию настолько полезной, что она входит в мои постоянные библиотеки "Утилиты Lua".

2 голосов
/ 22 марта 2012

Самый простой способ - добавить свойство index к каждому року:

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

Это правда, что вы можете вести вторую таблицу с индексами, но я считаю, что мой метод чище - когда приходит время удалять вещи, вам нужно беспокоиться только об одной таблице, главной.

Iу меня есть вопрос: зачем вам нужен этот индекс?В большинстве случаев достаточно хорошо разработанных функций прослушивателя событий, вам не нужно «находить» ваши объекты.Конечно, мне не хватает информации о том, что вы пытаетесь сделать, но, возможно, вы слишком усложняете вещи.

2 голосов
/ 19 марта 2012

Есть еще один способ сделать это, используя метаметоды. [Отредактировано, чтобы позволить вам удалить значения]

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 и взять его с собой; это также означает, что большую часть времени вам придется играть только с одной переменной - надеюсь, это уменьшит вероятность того, что вы попытаетесь получить доступ к неправильной вещи.

1 голос
/ 18 марта 2012

вы могли бы сделать что-то подобное, чтобы избавить вас от необходимости постоянно зацикливаться на таблице, чтобы найти индекс ...

RockTable = {}
RockIndicies = {}

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

тогда, когда вам нужно будет узнать индекс, вы можете просто использоватьрок вы должны проиндексировать RockIndices, чтобы быстро получить его.Если вы «удалите» камень, вы должны обязательно удалить его в обоих местах.

0 голосов
/ 18 марта 2012

К сожалению, вам понадобится перебрать стол, насколько мне известно.Хотя, чтобы знать, что на него нажали, вам не нужно было бы каким-то образом зацикливать их;и, следовательно, уже знаете индекс?

Редактировать

О, если у Corona нет какого-либо события обратного вызова для нажатия.Я никогда не использовал его, у меня есть опыт в Lua.

Вы можете сделать обратную ссылку, например так:

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

Тогда просто скажите rockNum = RocksB [rock]

Я почти уверен, что это должно сработать, но я не могу гарантировать это, хотя стоит попробовать.

Edit2

Метод грубой обработки будет выглядеть примерно так:

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