2014-12-15 2 views
3

문제가 있습니다. 내 프로그램에서 테이블의 한 필드를 체크해야합니다.테이블의 색인이 존재하는지 확인하십시오.

if(launchArgs.androidIntent.extras.notification.custom.test_field ~= nil)then... 

이 지수는 모든 것이 괜찮 존재하지만 존재하지 않을 때, 나는 오류 얻을 때 :

Attempt to index field 'notification' (a nil value). 

을 그리고 그것은 이해할 수있다. 해당 인덱스가 있는지 확인하는 방법은 무엇입니까?

+0

인가''notification'의 오타 notifiaction'? –

+0

@EtanReisner, 그게 중요한 것 같습니다. – lhf

+0

예. 오타였습니다. 나는 그것을 고쳤습니다. – Przemex3000

답변

5

각 테이블이 설정되어있는 경우이

if (launchArgs and launchArgs.androidIntent and launchArgs.androidIntent.extras 
    and launchArgs.androidIntent.extras.notification and launchArgs.androidIntent.extras.notification.custom 
    and launchArgs.androidIntent.extras.notification.custom.test_field) then 
-- do you stuff 
end 

이 코드는 확인합니다보십시오.

확실 발사 args.androidIntent.extras라면 항상 그냥이

if(launchArgs.androidIntent.extras.notification and launchArgs.androidIntent.extras.notification.custom and launchArgs.androidIntent.extras.notification.custom.test_field)then 
    -- do your stuff 
end 

을하거나 (여기에서도 도움이) 내가 다른 대답에 게시 된 것으로,이 기능을 사용할 수 있습니다 설정

function IndexScan(input,value,case,_type) 
    if (input and type(input) == 'table') then 
     if (_type) then 
      if (type(value) == _type and value == input) then 
       return true; 
      end 
     else 
      if (type(value) == 'table' and value == input) then 
       return true; 
      end 
     end 
     for key,object in pairs(input) do 
      if (case and type(input)=='string' and type(key)=='string') then 
       if (_type) then 
        if (value:lower() == key:lower() and type(object)==_type) then 
         return true; 
        elseif(type(object)=='table') then 
         return IndexScan(object,value,case,_type) 
        end 
       else 
        if (value:lower() == key:lower()) then 
         return true; 
        elseif(type(object)=='table') then 
         return IndexScan(object,value,case,_type) 
        end 
       end 
      else 
       if (_type) then 
        if (key == value and type(object)==_type) then 
         return true 
        elseif(type(object)=='table') then 
         return IndexScan(object,value,case,_type) 
        end 
       else 
        if (key == value) then 
         return true 
        elseif(type(object)=='table') then 
         return IndexScan(object,value,case,_type) 
        end 
       end 
      end 
     end 
    end 
    return false; 
end 
-- IndexScan(@param table(table), @param index(string), @param case-sensitive(true/false), @param type (index type, string/boolean/number/table ...)) 
-- checks if these two indexes were set any where in the launchArgs table and checks their type 
if (IndexScan(launchArgs,"notification",false,"table") and IndexScan(launchArgs,"test_field",false,"string")) then 
    -- do your stuff 
end 

편집 : 이 기능에 약간의 실수를 수정했습니다.

편집 : 작성자가 알림 오타를 수정 한 후 스크립트를 업데이트했습니다.

+1

더 짧은 대체 방법 :'local T = {}; if ((((launchArgs 또는 T) .androidIntent 또는 T) .extras 또는 T) .notification 또는 T) .custom 또는 T) .test_field 그런 다음 끝내기 – siffiejoe

+0

@siffiejoe 메서드는 시간이 걸리고 실제로 안전하지 않습니다. T는이 필드를 검사하기 전에 항상 설정됩니다). 그러나 처음 두 옵션과 옵션은 여전히 ​​약간의 시간이 걸립니다. 이 기능은 이상적입니다. – das

1

또한이 시도 :

function setglobal(name,value) 
    local t=_ENV 
    local f="_G" 
    for x in name:gmatch("[^.]+") do 
     if t[f]==nil then t[f]={} end 
     t=t[f] 
     f=x 
    end 
    t[f]=value 
end 

function getglobal(name) 
    local t=_ENV 
    for x in name:gmatch("[^.]+") do 
     t=t[x] 
     if t==nil then return nil,x end 
    end 
    return t 
end 

setglobal("launchArgs.androidIntent.extras.notification.custom.test_field",2014) 
print(getglobal("launchArgs.androidIntent.extras.notification.custom.test_field")) 
print(getglobal("launchArgs.androidIntent.extras.notifiaction.custom.test_field")) 

이 최상위 변수가 전역 변수라고 가정합니다. 필요에 따라 조정하십시오.

+2

이것은 LUA <5.2에서 작동하지 않습니다. 사용하고자하는 사용자는'_ENV' 대신'getfenv (0)'을 사용하십시오. – das

+3

@ user812331, 루아 5.2는 3 년 동안 나왔습니다 ...하지만 5.1 백 포트에 대해 감사드립니다. – lhf

+0

문제를 해결하기 위해 전역을 만들 필요가 없습니다. – kikito

0

당신은이를 사용할 수 있습니다

local function try(root, query) 
    local ids, len = {}, 0 
    for id in query:gmatch("%w+") do 
    len = len + 1 
    ids[len]= id 
    end 

    local node = root 
    for i=1,len do 
    if type(node) ~= 'table' then return nil end 
    node = node[ids[i]] 
    end 

    return node 
end 

사용법 :

local tbl = { a = { b = { c = { d = 1 } } } } 

print(try(tbl, 'a.b.c.d')) -- prints 1 
print(try(tbl, 'a.b.c.x')) -- prints nil 
print(try(tbl, 'a.x.c.d')) -- prints nil