Comment vérifier si une table contient un élément dans Lua?
Est-il une méthode pour vérifier si une table contient une valeur ? J'ai ma propre fonction (naïve), mais je me demandais si quelque chose de "Officiel" existait 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 principale raison pour laquelle j'utilise ces fonctions est d'utiliser des tables comme ensembles, c'est-à-dire sans éléments en double. Est-il autre chose que je pourrais utiliser ?
4 réponses
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.{[3] } Bien sûr, comme noté par d'autres (et comme pratiqué dans des langues plus anciennes que Lua), la solution à votre vrai problème est de changer de représentation. Lorsque vous avez des tables et que vous voulez des ensembles, vous transformez les tables en ensembles en utilisant l'élément set comme clé et true
comme valeur. +1 à interjay.
Je ne peux pas penser à une autre façon de comparer les valeurs, mais si vous utilisez l'élément de l'ensemble comme clé, vous pouvez définir la valeur à autre chose que nil. Ensuite, vous obtenez des recherches rapides sans avoir à rechercher la table entière.
Je sais que c'est un vieux post, mais je voulais ajouter quelque chose pour la postérité. La façon simple de gérer le problème que vous avez est de créer une autre table, de valeur à clé.
Ie. vous avez 2 tables qui ont la même valeur, une pointant une direction, une pointant 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 d'interroger la nouvelle table pour voir si elle a la clé "élément". Cela évite d'avoir à parcourir chaque valeur de l'autre table.
S'il S'avère que vous ne pouvez pas réellement utilisez 'element' comme clé, car ce n'est pas une chaîne par exemple, puis ajoutez une somme de contrôle ou 'toString' dessus par exemple, puis utilisez-la comme clé.
Pourquoi voulez-vous faire cela? Si vos tables sont très volumineuses, le temps nécessaire pour parcourir chaque élément sera important, 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 votre les tables sont très petites, alors cela importera beaucoup moins, en fait, il peut même être plus rapide d'itérer que d'avoir une autre recherche de carte.
Le libellé de la question suggère cependant fortement que vous avez un grand nombre d'éléments à traiter.