Как проверить, содержит ли таблица элемент в Lua?


есть ли способ проверить, содержит ли таблица значение ? У меня есть своя (наивная) функция, но мне было интересно, существует ли для этого что-то "официальное"? Или что-то более эффективное...

function table.contains(table, element)
  for _, value in pairs(table) do
    if value == element then
      return true
    end
  end
  return false
end

кстати, основная причина, по которой я использую эти функции, заключается в использовании таблиц в качестве наборов, т. е. без повторяющихся элементов. Есть ли что-то еще, что я мог бы использовать ?

4 81

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

формулировка вопроса предполагает, что у вас есть большое количество элементов для рассмотрения.