Domanda

Esiste un metodo per il controllo se una tabella contiene un valore? Io ho la mia propria funzione (naive), ma mi chiedevo se qualcosa di "ufficiale" esiste per questo? O qualcosa di più efficiente ...

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

Tra l'altro, il motivo principale che sto utilizzando questa funzione è quello di utilizzare le tabelle come set, cioè senza elementi duplicati. C'è qualcos'altro che potrei usare?

È stato utile?

Soluzione

È possibile inserire i valori come chiavi della tabella. Ad esempio:

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

C'è un esempio più pieno-caratterizzato qui .

Altri suggerimenti

Data la sua rappresentazione, la funzione è efficiente come si può fare. Naturalmente, come notato da altri (e praticata in lingue più vecchio di Lua), la soluzione al vostro problema vero è quello di cambiare la rappresentazione. Quando si dispone di tabelle e si desidera set, è trasformare le tabelle in gruppi utilizzando l'elemento impostato come chiave e true come valore. +1 a interjay.

Non riesco a pensare ad un altro modo per confrontare i valori, ma se si utilizza l'elemento del set come il tasto, è possibile impostare il valore a qualcosa di diverso da zero. Poi si arriva ricerche veloci, senza dover cercare l'intera tabella.

So che questo è un vecchio post, ma ho voluto aggiungere qualcosa per i posteri. Il modo più semplice di gestire il problema che si ha è di fare un altro tavolo, di valore per chiave.

es. hai 2 tabelle che hanno lo stesso valore, uno che punta in una direzione, uno indicando l'altro.

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

È quindi possibile interrogare la nuova tabella per vedere se ha il tasto 'elemento'. Questo evita la necessità di scorrere ogni valore della tabella.

Se si scopre che non si può effettivamente utilizzare il 'elemento' come una chiave, perché non è una stringa, ad esempio, quindi aggiungere un checksum o tostring su di esso per esempio, e quindi utilizzare tale come chiave.

Perché vuoi fare questo? Se le tabelle sono molto grandi, la quantità di tempo per scorrere attraverso ogni elemento sarà significativo, si impedisce di fare molto spesso. L'overhead di memoria aggiuntiva sarà relativamente piccola, come verrà memorizza 2 puntatori allo stesso oggetto, anziché 2 copie dello stesso oggetto. Se le tabelle sono molto piccole, poi si importa molto meno, infatti può anche essere più veloce per iterare che avere un'altra mappa di ricerca.

La formulazione della domanda suggerisce tuttavia vivamente di avere un gran numero di elementi da affrontare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top