Сравнение таблиц Lua в таблицах - PullRequest
0 голосов
/ 21 февраля 2012

Итак, у меня есть таблица, которая содержит ссылки на другие таблицы, такие как:

local a = newObject()
a.collection = {}
for i = 1, 100 do
    local b = newObject()
    a[#a + 1] = b
end 

Теперь, если я хочу увидеть, находится ли конкретный объект в пределах "a", я должен использовать пары следующим образом:

local z = a.collection[ 99 ]
for i,j in pairs( a.collection ) do
    if j == z then
    return true
  end
end

Объект z находится на 99-м месте, и мне нужно было бы дождаться, пока пары будут повторяться по всем остальным 98 объектам. Эта настройка заставляет мою программу сканировать. Есть ли способ сделать какой-то ключ, который не является строкой или таблицей для сравнения, что является одним вкладышем? Как:

if a.collection[{z}] then return true end

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 21 февраля 2012

Почему вы храните объект в ячейке значения, а не в ячейке ключа таблицы?

local a = newObject()
a.collection = {}
for i = 1, 100 do
    local b = newObject()
    a.collection[b] = i
end 

чтобы увидеть, находится ли конкретный объект внутри "a"

return a.collection[b]

Если вам нужен целочисленный индексированный доступ к коллекции, сохраните его двумя способами:

local a = newObject()
a.collection = {}
for i = 1, 100 do
    local b = newObject()
    a.collection[i] = b
    a.collection[b] = i
end 

Вывод:

local z = a.collection[99]
if a.collection[z] then return true end
1 голос
/ 21 февраля 2012

Не знаю, быстрее это или нет, но, возможно, это поможет:

Наполнитель:

local a = {}
a.collection = {}
for i = 1, 100 do
    local b = {}
    a.collection[b] = true  -- Table / Object as index
end

Вывод:

local z = a.collection[99]
if a.collection[z] then return true end

Если это не то, что вы хотели сделать, вы можете разбить весь массив на меньшие сегменты и использовать хеш, чтобы отслеживать, какой объект принадлежит какому сегменту.

0 голосов
/ 21 февраля 2012

Возможно, вы захотите перейти от использования пар () к использованию регулярного цикла for и индексирования таблицы, пар () кажется медленнее в больших коллекциях таблиц.

for i=1, #a.collection do
    if a.collection[i] == z then
        return true
    end
end

Я сравнилскорость итерации по коллекции в 1 миллион таблиц с использованием обоих пар () и индексации таблиц, причем индексация каждый раз выполнялась немного быстрее.Попробуйте сами, используя os.clock () для профилирования вашего кода.

Я не могу придумать более быстрый способ вашего решения, кроме использования какой-либо хэш-функции для установки уникальных индексов в a.collection.Таблица.однако выполнение этого сделало бы получение конкретной таблицы нетривиальной задачей (вы не могли бы просто выполнить a.collection [99], вам пришлось бы выполнять итерацию, пока вы не нашли нужную таблицу), но затем выможет легко проверить, была ли таблица в a.collection, выполнив что-то вроде a.collection [hashFunc (z)] ~ = nil ...)

...