Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How to combine two tables? Where table A overwrites table B.

Asked by 5 years ago

Table A = data (not Data) Table B = CompTable

I'm trying to combine A with B, where A overwrites B, but if something exists in B but not in A, B adds the value to A. I've tried several times and I'm currently lost..

"attempt to index field '?' (a nil value)"

local CompTable = {
    ["Stats"] = {
        ["Money"] = 100;
        ["Exp"] = 0;
        ["Placements"] = {
            ["PropA"] = {
                ["Rotation"] = 2;
                ["Position"] = Vector2.new(1, 5)
            };
        };
        ["Inventory"] = {
            ["1"] = 10945;
        };
    };
    ["Time"] = {
        ["LastJoin"] = false;
        ["LastCrate"] = false;
    };
    ["Settings"] = {
        ["DarkUITheme"] = false;
        ["BlurFX"] = false;
        ["ColorCorrectionFX"] = false;
    };
}

function module:combineTables(data)
    if not data or data == false then return CompTable end
    local DataTable = {}
    local pass, reason = pcall(function()
        for Index, DString in pairs(CompTable) do
            DataTable[tostring(Index)] = {}
            for Index2, DString2 in pairs(DString) do
                if data[tostring(Index)][tostring(Index2)] == true then --error
                    DataTable[tostring(Index)][tostring(Index2)] = data[tostring(Index)][tostring(Index2)]
                else
                    DataTable[tostring(Index)][tostring(Index2)] = DString
                end
            end
        end
    end)
    print(pass, reason)
    return DataTable
end
0
By the way, if you're merging in player data, this is super smart, and I highly recommend it. Avoids issues where players join old servers and then new servers! Avigant 2374 — 5y

1 answer

Log in to vote
0
Answered by
Avigant 2374 Moderation Voter Community Moderator
5 years ago
Edited 5 years ago

Here's my simple deep table merging function. It doesn't handle metatables or other edge cases:

function TableUtility.Merge(Mergee, Merger, IsMergerOverwriter)
    local Merged = {}

    for MergeeKey, MergeeValue in pairs(Mergee) do
        Merged[MergeeKey] = MergeeValue
    end

    for MergerKey, MergerValue in pairs(Merger) do
        local MergeeValue = Mergee[MergerKey]

        if type(MergeeValue) == "table" and type(MergerValue) == "table" then
            Merged[MergerKey] = TableUtility.Merge(MergeeValue, MergerValue, IsMergerOverwriter)
        elseif Merged[MergerKey] or IsMergerOverwriter then
            Merged[MergerKey] = MergerValue
        end
    end

    return Merged
end

If the two values are tables, it makes a recursive call to merge them. Otherwise, if IsMergerOverwriter is true, the value of the key in the mergee will be set to the value of the key in the merger, even if the key doesn't exist in the mergee.

0
Ahhh, I see how that works. It's easy when you spend a few minutes and break down exactly what you're trying to do. Thanks! LetterSlayer 42 — 5y
Ad

Answer this question