Вопрос

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

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

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

Это было полезно?

Решение

Вы можете поместить значения в качестве ключей таблицы.Например:

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 к междометию.

Я не могу придумать другого способа сравнения значений, но если вы используете элемент набора в качестве ключа, вы можете установить значение любым, кроме nil.Тогда вы получаете быстрый поиск без необходимости выполнять поиск по всей таблице.

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

т. е.у вас есть 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

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

Если выяснится, что на самом деле вы не можете использовать 'element' в качестве ключа, потому что это, например, не строка, то добавьте контрольную сумму или tostring на нем, например, а затем используйте это в качестве ключа.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top