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

How to send table as an argument in order?

Asked by
NykoVania 231 Moderation Voter
1 year ago
Edited 1 year ago

I'm trying to send a table to a module, but the module doesn't receive the table in the same order as it is sent.

Main Script:

local Frame = FrameworkModule.FrameworkStuff(
    CurrentHitbox,
    Player,
    Modded,
    {
        Hits = 1,
        Debounce = 5,
        WeldToPart = false,
        OffSet1 = 0,
        OffSet2 = 0,
        OffSet3 = 0,    
    })

Module Script:

function Module:FrameworkStuff(Info)
    Hits,Debounce,WeldToPart,WeldToPartOffset1,WeldToPartOffset2,WeldToPartOffset3 =
        table.unpack(Info)[1],
        table.unpack(Info)[2],
        table.unpack(Info)[3],
        table.unpack(Info)[4],
        table.unpack(Info)[5],
        table.unpack(Info)[6]
    print(Hits)
    print(Debounce)
    print(WeldToPart)
    print(WeldToPartOffset1)
    print(WeldToPartOffset2)
    print(WeldToPartOffset3)

The console will print it as:

{
["Debounce"] = 5,
["Hits"] = 1,
["OffSet1"] = 0,
["OffSet2"] = 0,
["OffSet3"] = 0,
["WeldToPart"] = false
}

This is not the order I sent the table in, how could I make it print as this instead?

{
["Debounce"] = 5,
["Hits"] = 1,
["WeldToPart"] = false,
["OffSet1"] = 0,
["OffSet2"] = 0,
["OffSet3"] = 0
}

1 answer

Log in to vote
3
Answered by 1 year ago
Edited 1 year ago

The problem is with your data structure. When it comes to tables in Lua, there are two data structures:

  • Array
    • {"a", "b", ...}
  • Dictionary
    • {a = "a", b = "b", ...}

(there is technically a third data structure if you count mixed tables, but that's another topic)

A general rule of thumb when it comes to structuring your data:

If you care about order, use an array. If you care about keys, use a dictionary. If you care about both, use both!

What's the Difference?

Arrays and dictionaries work fundamentally differently under the hood. I'll spare the details of the technicalies, but here's the rundown:

  • Array

    • Cares about order (preserves the order of values in the table).
    • Easy to compute size (such as using the # operator)
    • Access to most of the functions in the table library (as they're geared towards manipulating arrays)
  • Dictionary

    • Doesn't care about order, cares about key/value pairs.
    • No intrinsic way to compute size (you have to manually loop over the table and count iterations)
    • Only holds unique keys (you can guarantee each key in a dictionary table will be unique)

How can I use Both?

As long as you're consistent with how you create keys in your table, then you're structure will remain the same. The values in your table do not determine the data structure of the parent table.

For example, you can have a dictionary that holds arrays:

local dict = {
    keyA = {"a", "b", "c"},
    keyB = {"d", "e", "f"},
    ...
}

...and you can have an array that holds dictionaries:

local array = {
    { key = 'value' },
    { key = 'value' },
    ...
}

You will often see examples of the second structure mentioned above in numerous places. This is a popular method of storing dynamic data while preserving order.

Your Solution

In your case however, I don't see a reason to nest dictionaries in arrays or vise-versa. The only way to practically achieve what you're looking for is to create an array of arrays.

For example, instead of doing this and having no control over the order of your key/values:

{
    ["Debounce"] = 5,
    ["Hits"] = 1,
    ["OffSet1"] = 0,
    ["OffSet2"] = 0,
    ["OffSet3"] = 0,
    ["WeldToPart"] = false
}

...you could create an array of child arrays, where each child array stores the key in the first index and the value in the seocnd index:

{
    { "Debounce", 5 },
    { "Hits", 1 },
    { "OffSet1", 0 },
    { "OffSet2", 0 }
    { "OffSet3", 0 }
    { "WeldToPart", false }
}

if you really care about keeping this structure as a dictionary, then you could simply convert it back into a dictionary by doing:

local dataArray = {
    { "Debounce", 5 },
    { "Hits", 1 },
    { "OffSet1", 0 },
    { "OffSet2", 0 }
    { "OffSet3", 0 }
    { "WeldToPart", false }
}

local convertDataArrayToDict = function(array)
    local dict = {};

    for i = 1, #array do
        local data = array[i];
        dict[data[1]] = data[2];
    end

    return dict;
end

now calling convertDataArrayToDict(dataArray) will return something like this:

{
    ["Debounce"] = 5,
    ["Hits"] = 1,
    ["OffSet1"] = 0,
    ["OffSet2"] = 0,
    ["OffSet3"] = 0,
    ["WeldToPart"] = false
}

Just remember that the returned dictionary will still not be in any particular order. This is only if you want to preserve the original structure.

Hope this helps, let me know if you have any questions!

1
Thank you, this helped a lot. NykoVania 231 — 1y
0
Glad to hear it! ScriptGuider 5640 — 1y
Ad

Answer this question