Как проверить, содержит ли таблица элемент в Lua?
есть ли способ проверить, содержит ли таблица значение ? У меня есть своя (наивная) функция, но мне было интересно, существует ли для этого что-то "официальное"? Или что-то более эффективное...
function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
кстати, основная причина, по которой я использую эти функции, заключается в использовании таблиц в качестве наборов, т. е. без повторяющихся элементов. Есть ли что-то еще, что я мог бы использовать ?
4 ответа:
вы можете поместить значения в качестве ключей таблицы. Например:
function addToSet(set, key) set[key] = true end function removeFromSet(set, key) set[key] = nil end function setContains(set, key) return set[key] ~= nil end
есть более полнофункциональный пример здесь.
учитывая ваше представительство, ваша функция настолько эффективна, насколько это возможно. конечно, как отмечают другие (и как практикуется в языках старше Lua), решение вашей реальной проблемы заключается в изменении представления. Когда у вас есть таблицы и вы хотите наборы, вы превращаете таблицы в наборы, используя элемент set в качестве ключа и
true
Как значение. +1 к interjay.
Я не могу придумать другой способ сравнения значений, но если вы используете элемент набора в качестве ключа, вы можете установить значение, отличное от нуля. Затем вы получаете быстрый поиск без необходимости поиска по всей таблице.
Я знаю, это старый пост, но я хотел добавить что-то для потомков. Простой способ обработки проблемы, что у вас есть, чтобы сделать другую таблицу, значение для ключа.
ie. у вас есть 2 таблицы, которые имеют одинаковое значение, одно указывает в одном направлении, одно указывает на другое.
function addValue(key, value) if (value == nil) then removeKey(key) return end _primaryTable.key = value _secodaryTable.value = key end function removeKey(key) local value = _primaryTable.key if (value == nil) then return end _primaryTable.key = nil _secondaryTable.value = nil end function getValue(key) return _primaryTable.key end function containsValue(value) return _secondaryTable.value ~= nil end
затем вы можете запросить новую таблицу, чтобы узнать, имеет ли она ключ "элемент". Это предотвращает необходимость перебора всех значений другой таблицы.
если получится что вы не можете фактически использовать "элемент" в качестве ключа, потому что это не строка, например, а затем добавить контрольную сумму или "toString" на нем, например, а затем использовать его в качестве ключа.
почему вы хотите это сделать? Если ваши таблицы очень велики, количество времени для итерации по каждому элементу будет значительным, что не позволит вам делать это очень часто. Дополнительные затраты памяти будут относительно небольшими, так как они будут хранить 2 указателя на один и тот же объект, а не 2 копии того же самого объекта. Если ваши таблицы очень малы, то это будет иметь гораздо меньшее значение, поскольку итерация может быть даже быстрее, чем другой Поиск Карты.
формулировка вопроса предполагает, что у вас есть большое количество элементов для рассмотрения.