2017-10-15 1 views
1

그래서 여기서 뭘 하려는지 cjson을 사용하여 테이블로 json_body을 디코딩 한 것입니다. 구성 가능한 값 conf로 주어진 요소를 제거하려고합니다. .remove.json, 나는 꽤 가까이에 있지만 여전히 작동하지 않는다고 느낍니다. 더 좋은 방법이 있습니까? 테이블을 "깊이"찾아서 conf.remove.json = I.want.to.remove와 같은 손쉬운 방법으로 접근 할 수있는 안전한 방법이 있습니까? json_table [I] [want] [to] [remove] [this ] = NPE 일종의 던지기없이 nil?Lua 중첩 된 Json, 단일 발생 제거 또는 여러 경우에 발생하는 목록

local configRemovePath= {} 
local configRemoveDepth= 0 
local recursiveCounter = 1 

local function splitString(inputstr) 
     sep = "%." --Split on . 
     configRemovePath={} 
     configRemoveDepth=0 

      for str in string.gmatch(inputstr, "([^"..sep.."]+)") do 
       configRemovePath[configRemoveDepth + 1] = str 
       configRemoveDepth = configRemoveDepth + 1 
     end 
end 

local function recursiveSearchAndNullify(jsonTable) 
    for key, value in pairs(jsonTable) do --unordered search 
    -- First iteration 
    --Sample Json below, where conf.remove.json = data.id and nothing happened. conf.remove.json=data.id 
    --{ 
    --"data": { 
     -- "d": 2, 
    -- "id": 1 
    --} 
     --} 
    -- value = {"d": 2, "id": 1}, key = "data", configRemovePath[recursiveCounter] = "data" , configRemovePath ['data','id'] , configRemoveDepth = 2 

    if(type(value) == "table" and value == configRemovePath[recursiveCounter] and recursiveCounter < configRemoveDepth) then --If the type is table, the current table is one we need to dive into, and we have not exceeded the configurations remove depth level 
     recursiveCounter = recursiveCounter + 1 
     jsonTable = recursiveSearchAndNullify(value) 
    else 
     if(key == configRemovePath[recursiveCounter] and recursiveCounter == configRemoveDepth) then --We are at the depth to remove and the key matches then we delete. 
      for key in pairs (jsonTable) do --Remove all occurances of said element 
       jsonTable[key] = nil 
       end 
     end 
    end 
    end 
    return jsonTable 
end 

for _, name in iter(conf.remove.json) do 
    splitString(name) 
    if(configRemoveDepth == 0) then 
     for name in pairs (json_body) do 
      json_body[name] = nil 
      end 
    else 
    recursiveCounter = 1 --Reset to 1 for each for call 
    json_body = recursiveSearchAndNullify(json_body) 
    end 
end 

누구에게 도움을 주신 분 덕분에, 이것은 루아와의 첫날이기 때문에 나는 꽤 새로운 사람입니다.

답변

0

이것은 공식적인 답변이며 Christian Sciberras의 도움을 받아 더 나은 방법을 찾았습니다!

local json_body_test_one = {data = { id = {"a", "b"},d = "2" }} --decoded json w cjson 
local json_body_test_two = {data = { { id = "a", d = "1" }, { id = "b", d = "2" } } } 
local config_json_remove = "data.id" 

local function dump(o) --Method to print test tables for debugging 
    if type(o) == 'table' then 
     local s = '{ ' 
     for k,v in pairs(o) do 
     if type(k) ~= 'number' then k = '"'..k..'"' end 
     s = s .. '['..k..'] = ' .. dump(v) .. ',' 
     end 
     return s .. '} ' 
    else 
     return tostring(o) 
    end 
end 

local function splitstring(inputstr, sep) 
    if sep == nil then 
    sep = "%." --Dot notation default 
    end 
    local t={} ; i=1 
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do 
    t[i] = str 
    i = i + 1 
    end 
    return t 
end 

local function setjsonprop(json_object, path, newvalue) 
    local configarray = splitstring(path) 
    while (#configarray > 1) do 
    json_object = json_object[table.remove(configarray, 1)] 
    if(type(json_object) == "table" and #json_object > 0) then 
     local recursepath = table.concat(configarray, ".") 
     for _, item in pairs(json_object) do 
      setjsonprop(item, recursepath, newvalue) 
     end 
     return 
    end 
    end 

    json_object[table.remove(configarray, 1)] = newvalue 
end 

setjsonprop(json_body_test_one, config_json_remove, nil) 
print(dump(json_body_test_one))