2016-10-14 1 views
2

J'ai une valeur armyName et j'ai besoin d'une fonction qui vérifie si c'est l'une des 8 valeurs. Comme je suis nouveau à Lua, je cherche la meilleure façon de faire ce genre de test.Déterminer si la variable est l'une des plusieurs valeurs dans Lua

Cela fonctionne:

local function isPlayerArmyName(armyName) 
    return armyName == "ARMY_1" 
     or armyName == "ARMY_2" 
     or armyName == "ARMY_3" 
     or armyName == "ARMY_4" 
     or armyName == "ARMY_5" 
     or armyName == "ARMY_6" 
     or armyName == "ARMY_7" 
     or armyName == "ARMY_8" 
end 

Cela fonctionne aussi:

local function isPlayerArmyName(armyName) 
    local names = { 
     ["ARMY_1"] = true, ["ARMY_2"] = true, ["ARMY_3"] = true, ["ARMY_4"] = true, 
     ["ARMY_5"] = true, ["ARMY_6"] = true, ["ARMY_7"] = true, ["ARMY_8"] = true, 
    } 

    return names[armyName] or false 
end 

Ils sont à la fois plutôt ridicule par rapport à ce code PHP:

return in_array($armyName, [ "ARMY_1", "ARMY_2", "ARMY_3", ..., "ARMY_8" ]) 

Y at-il une meilleure façon de faire une telle vérification que les extraits de code Lua fournis? Et sinon, que préfèrerait le programmeur Lua typique? le premier ou le second? J'utilise Lua 5.0.

+0

Utilisez une fermeture avec la deuxième méthode. – hjpotter92

+0

Je ne comprends pas votre suggestion –

Répondre

4

Vous pouvez le faire ainsi:

local names = {"ARMY_1", "ARMY_2", "ARMY_3", "ARMY_4", "ARMY_5", "ARMY_6", "ARMY_7", "ARMY_8"} 

local function isPlayerArmyName(armyName) 
    for index = 1, #names do 
     if names[index] == armyName then 
      return true 
     end 
    end 
end 

Cette option est évolutive, puisque vous pouvez ajouter de nouvelles armées dans le cas où votre mise en œuvre doit changer. Vous pouvez extraire la partie for à votre propre fonction in_array, que vous pouvez utiliser dans tout votre code:

local function in_array(value, array) 
    for index = 1, #array do 
     if array[index] == value then 
      return true 
     end 
    end 

    return false -- We could ommit this part, as nil is like false 
end 

local armyNames = {"ARMY_1", "ARMY_2", "ARMY_3", "ARMY_4", "ARMY_5", "ARMY_6", "ARMY_7", "ARMY_8"} 

local function isPlayerArmyName(armyName) 
    return in_array(armyName, armyNames) 
end 

Cette mise en œuvre pourrait être un peu plus lent que votre deuxième option, puisque votre deuxième option utilise des clés. Votre deuxième option n'est pas mauvaise, elle pourrait même être la plus rapide. Cela a l'air idiot, mais il est facilement configurable.

Vous pouvez également utiliser un match de motif, si la table n'est pas nécessaire et tenir à cette convention de nommage de l'armée:

local function isPlayerArmyName(armyName) 
    return (string.match(armyName, "^ARMY_[1-8]$")) ~= nil 
end 

Vous pouvez même retirer le ~= nil, car il retournera une chaîne, qui est aussi vrai dans Lua:

local function isPlayerArmyName(armyName) 
    return string.match(armyName, "^ARMY_[1-8]$") 
end 

if isPlayerArmyName("ARMY_1") then 
    -- This will be executed, since it returned "ARMY_1", which evaluates to true 
end 

if isPlayerArmyName("ARMY_9") then 
    -- This will not be executed, since the function returned nil. 
end 

en ce qui concerne le premier exemple que vous fournissez, je ne recommanderais pas le faire car il n'est pas modulaire ou évolutive, pas Lua et non dans une autre langue.

+0

Je n'aime pas votre solution parce que vous créez une nouvelle table chaque fois que vous appelez la fonction. – warspyking

+0

Vraiment? Ceci est juste un exemple de code. Je ne vois pas pourquoi la création d'une table (qui sera finalement GC) est une telle préoccupation. Quoi qu'il en soit, votre solution crée également une table, si je devais l'appeler de cette façon tout le temps. –

+0

Nos codes sont très différents. Je permets de personnaliser la table à chaque appel, il n'y a aucune raison pour que vous ne puissiez pas stocker la vôtre dans une valeur supérieure. (Je suis grand sur l'efficacité, et très difficile, alors ignorez-moi si vous voulez. – warspyking

0
function in_array(v, t) 
    for i=1,#t do 
    if v == t[i] then return true end 
    end 
end 

if in_array(v, {....}) then .... end 
+1

Son deuxième code est meilleur que le vôtre – Vyacheslav

+0

@Vyacheslav Je pense que l'idée ici est que c'est ainsi que vous implémenteriez l'équivalent de 'in_array' de PHP, et qu'il existe différents outils pour différentes structures de données . Je dirai que les réponses au code seulement ne sont pas une bonne chose. – Oka

2
function in_dictionary(val,dict) 
    return dict[val] 
end 

print(in_dictionary("potatoes", {apples = true, potatoes = true, oranges = true})) 

Probablement le meilleur moyen de le faire.