Existe-t-il une méthode pour vérifier si une table contient une valeur? J'ai ma propre fonction (naïve), mais je me demandais s'il existait quelque chose d '"officiel" pour cela? Ou quelque chose de plus efficace ...
function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
En passant, la raison principale pour laquelle j'utilise cette fonction est d'utiliser des tableaux en tant qu'ensembles, c'est-à-dire sans éléments dupliqués. Y a-t-il autre chose que je pourrais utiliser?
Vous pouvez mettre les valeurs comme clés de la table. Par exemple:
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
Il y a un exemple plus complet ici .
Compte tenu de votre représentation, votre fonction est aussi efficace que possible. Bien sûr, comme l'ont noté d'autres personnes (et pratiquées dans des langues plus anciennes que Lua), la solution à votre problème réel est de changer de représentation. Lorsque vous avez des tables et que vous voulez des jeux, vous transformez les tables en jeux en utilisant l'élément set en tant que clé et true
en tant que valeur. +1 à l'interjay.
Je ne vois pas d'autre moyen de comparer les valeurs, mais si vous utilisez l'élément de l'ensemble comme clé, vous pouvez définir la valeur sur autre chose que nil. Vous obtenez alors des recherches rapides sans avoir à chercher dans toute la table.
Je sais que ceci est un ancien post, mais je voulais ajouter quelque chose pour la postérité. La manière simple de traiter le problème que vous avez est de créer une autre table, d’une valeur à l’autre.
c'est à dire. vous avez 2 tables qui ont la même valeur, l'une pointant dans une direction, l'une pointant dans l'autre.
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
Vous pouvez ensuite interroger la nouvelle table pour voir si elle a la clé 'element'. Cela évite d'avoir à parcourir chaque valeur de l'autre table.
S'il s'avère que vous ne pouvez pas réellement utiliser l'élément comme clé, parce que ce n'est pas une chaîne par exemple, ajoutez une somme de contrôle ou tostring
par exemple, puis utilisez-la comme clé. .
Pourquoi veux-tu faire cela? Si vos tables sont très grandes, le temps nécessaire pour parcourir chaque élément sera considérable, ce qui vous empêchera de le faire très souvent. La surcharge de mémoire supplémentaire sera relativement faible, car elle stockera 2 pointeurs sur le même objet, plutôt que 2 copies du même objet. Si vos tables sont très petites, cela importera beaucoup moins. En fait, il peut même être plus rapide à itérer que d'avoir une autre recherche sur la carte.
Le libellé de la question suggère toutefois fortement que vous ayez un grand nombre de points à traiter.