2017-06-17 1 views
1

Je suis nouveau à Lua et j'ai juste essayé de faire quelque chose de commun et simple dans d'autres langages mais qui ne fonctionne pas de la même manière dans Lua en raison des paramètres des fonctions passées par référence (je suppose) . Ajoutant aussi des choses aux tables est fait par référence aussi il semble. Pseudo-code:Comment est-ce que je fais l'équivalent de passer des paramètres par valeur dans Lua?

objImage --stores details about each image like name, iso, aperture etc. 
tblMetadata --table that has all the image names and associated data. 
tblImages --table to hold the image objects (objImage) 

for each line in tblMetadata 
    objImage.name = blahblah 
    objImage.iso = blahblah 
    etc... 
    table.insert(tblImages, objImage) 
    objImage = nil 
end 

Dans la plupart des langues que je l'ai utilisé, objImage = nil (ou l'équivalent) remet à zéro l'objet pour permettre une nouvelle image à ajouter à la table. Mais dans Lua, il place l'objet juste ajouté à la table à zéro. Quelle est la technique pour ajouter une série d'objets à une table de manière itérative comme ceci? J'ai essayé d'utiliser une deuxième objImage (objImage2) et en lui affectant objImage avant de l'ajouter (objImage2) à la table, mais cela assigne juste un pointeur/référence à l'objImage original.

Edit: Mon code pseudo ne reflète pas pleinement ce que je suis en train de le faire, donc je l'ai ajouté le code réel ci-dessous:

function extractExif(tblOutput) 
    local tblImages = {} 
    local blnFlag = false 
    local intCount = 0 
    local Image = {} --pseudo object to hold metadata for each image 

    for k,v in pairs(tblOutput) do --iterate through each value in the table 
     if string.find(v, "^=.+") then 
      --test if new image other than the first one 
      if blnFlag == true then 
      --add Image to tblImages and then clear Image object 
      table.insert(tblImages, Image) 
      Image = nil 
      blnFlag = false 
      end 

      i, j = string.find(v, "/") -- **** MAC ONLY. Back slash for Windows ***** 
      Image.filePath = string.sub(v, i) --returns the file path 
      --Image.name = string.match(v, "([^/]+)$") --return the file name 
      blnFlag = true 

     elseif string.find(v, "ISO") ~= nil then 
      Image.iso = string.match(v, "%a+:(.+)") --get text (i.e value) to right of colon 
     elseif string.find(v, "Film") ~= nil then 
      Image.filmSim = string.match(v, "%a+:(.+)") 
     elseif string.find(v, "Setting") ~= nil then 
      Image.drMode = string.match(v, "%a+:(.+)") 
     elseif (string.find(v, "Auto") ~= nil) or (string.find(v, "Development") ~= nil) then -- corresponds to "Auto Dynamic Range" and "Development Dynamic Range" in fuji exif 
      Image.dr = string.match(v, "%a+:(.+)") 
     else 

     end 
    end 
end 

je peux de programme de cours ce mieux en utilisant une table imbriquée ou similaire au lieu d'une liste de métadonnées tblOutput plat, et je le ferai probablement à un moment donné.

+0

est ce code correct? qu'est-ce que la variable 'objTable'? peux-tu coller du vrai code? – pkisztelinski

+0

Désolé, cela devrait être objImage. Je l'ai corrigé. – erv

Répondre

3

probablement vous devez réinitialiser objImage en utilisant la table vide au lieu de la valeur nil.

par exemple:

local objImage = {} 
local tblMetadata = {'foo', 'bar', 'biz'} 
local tblImages = {} 

for k, v in ipairs(tblMetadata) do 
    objImage.name = v 
    objImage.iso = v 
    table.insert(tblImages, objImage) 
    objImage = {} 
end 
+0

Ah mec, j'étais certain d'avoir essayé ça. Oui, ça le corrige. Merci. – erv

+1

Cela rendrait la localité plus claire pour déplacer la déclaration d'objImage dans la boucle. De cette façon, vous n'auriez pas besoin de l'affectation finale. Vous pouvez même remplir la table avec ses deux champs en utilisant le constructeur de la table. Ensuite, vous pouvez aligner le constructeur de la table pour que le corps de la boucle n'ait qu'une seule instruction. 'table.insert (tblImages, {name = v, iso = v})' –

+0

Voir ma réponse à la réponse d'Egor, @TomBlodget – erv

1
for each line in tblMetadata 
    -- Create new LOCAL empty instance 
    local objImage = {} 
    -- Fill the data 
    objImage.name = blahblah 
    objImage.iso = blahblah 
    etc... 
    table.insert(tblImages, objImage) 
    -- There is no need for assigning nil to variable objImage 
    -- objImage is being garbage-collected automatically as it goes out of scope 
end 
+0

Malheureusement, je ne peux pas faire cela car chaque image nécessite plusieurs itérations à travers la boucle for pour obtenir son ensemble de données complet. Fondamentalement, le tblMetadata est comme ceci: IMG_123.jpg/n ISO: 200/n etc .../n IMG_124.jpg/n ISO: 800/n etc ... – erv

+0

Désolé, mon code pseudo ISN pas complètement précis. Essentiellement, je veux savoir comment le faire d'une manière équivalente à la façon dont cela est fait dans d'autres langues. Donc, le pseudo code ci-dessus s'applique toujours dans ce sens. – erv