lualuau

Apply key values to a dictionary from a dictionary


The title says it all. I want to do an operation to apply key values to a dictionary from a dictionary Here, I'll explain what I meant.

I have these long dictionaries initialized in my code.

local globalDefault = {
    ["LastPlayed"] = "",
    ["Grades"] = {
        ["Grade"] = 1,
        ["Level"] = 1
    },
    ["Challenge"] = {
        ["History"] = {}
    },
    ["Settings"] = {
        ["ScrollFrameHitbox"] = false
    }
}

local globalData = {
    ["Settings"] = {
        ["ScrollFrameHitbox"] = true
    }
}

I want to apply all globalData's key values to globalDefault. This is what globalDefault dictionary should look like after applying them:

{
    ["LastPlayed"] = "",
    ["Grades"] = {
        ["Grade"] = 1,
        ["Level"] = 1
    },
    ["Challenge"] = {
        ["History"] = {}
    },
    ["Settings"] = {
        ["ScrollFrameHitbox"] = true
    }
}

How can I do such a simple operation?


Solution

  • The function:

    function deepApply (default, new)
        for key, value in pairs (new) do
            if type (value) == "table" then
                if not default[key] then
                    default[key] = {}
                    print ('created table ['..key..']')
                end
                local def2 = default[key]
                local new2 = new[key]
                deepApply (def2, new2)
            elseif default[key] ~= new[key] then
                print ('updated ['..key..'] from ['..tostring(default[key])..'] to ['..tostring(new[key])..']')
                default[key] = new[key]
            end
        end
    end
    

    Example:

    local globalDefault = {
        ["LastPlayed"] = "",
        ["Grades"] = {
            ["Grade"] = 1,
            ["Level"] = 1
        },
        ["Challenge"] = {
            ["History"] = {}
        },
        ["Settings"] = {
            ["ScrollFrameHitbox"] = false
        }
    }
    
    local globalData = {
        ["Settings"] = {
            ["ScrollFrameHitbox"] = true
        },
        ["NewSettings"] = {
            ["IsFun"] = true
        },
    }
    
    deepApply (globalDefault, globalData)
    
    serpent = require ('serpent')
    
    print (serpent.block (globalDefault))
    

    Result:

    created table [NewSettings]
    updated [IsFun] from [nil] to [true]
    updated [ScrollFrameHitbox] from [false] to [true]
    {
        Settings = {
            ScrollFrameHitbox = true
        },
        Challenge = {
            History = {}
        },
        NewSettings = {
            IsFun = true
        },
        LastPlayed = "",
        Grades = {
            Level = 1,
            Grade = 1
        }
    }