126

テーブルに値が含まれているかどうかを確認する方法はありますか? 私は独自の(素朴な)機能を持っていますが、そのために「公式」が存在するかどうか疑問に思っていましたか?それとももっと効率的な...

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

ところで、私がこの関数を使用している主な理由は、テーブルをセットとして使用することです。つまり、要素が重複しないようにするためです。他に使えるものはありますか?

4

5 に答える 5

141

値をテーブルのキーとして配置できます。例えば:

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

より完全な機能を備えた例がここにあります。

于 2010-02-17T16:44:03.320 に答える
26

あなたの表現を考えると、あなたの機能は可能な限り効率的です。 もちろん、他の人が指摘しているように (そして Lua よりも古い言語で実践されているように)、実際の問題の解決策は表現を変更することです。テーブルがあり、セットが必要な場合は、set 要素をキーおよび値として使用して、テーブルをセットに変換しtrueます。インタージェイに+1。

于 2010-02-17T17:17:06.690 に答える
3

これが古い投稿であることは知っていますが、後世のために何かを追加したかったのです。あなたが抱えている問題を処理する簡単な方法は、値からキーへの別のテーブルを作成することです。

すなわち。同じ値を持つ 2 つのテーブルがあり、1 つは一方向を指し、もう 1 つは別の方向を指しています。

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 つのポインターを格納するため、追加のメモリ オーバーヘッドは比較的小さくなります。テーブルが非常に小さい場合は、それほど重要ではありません。実際には、別のマップ ルックアップを行うよりも反復する方が速い場合もあります。

ただし、質問の文言は、対処するアイテムが多数あることを強く示唆しています。

于 2013-09-02T09:15:40.810 に答える
2

値を比較する別の方法が思い浮かびませんが、セットの要素をキーにすれば、値を nil 以外に設定できます。これにより、テーブル全体を検索しなくても、高速に検索できます。

于 2010-02-17T16:43:37.563 に答える