How to force a dictionary to go in order.

  • Global Moderator

    Title is misleading, yes, since a dictionary isn't being used. Sorry about that.

    You should already know that dictionaries do not impose an order on their values, whilst arrays do.

    Take this little snippet as an example

    local t = {
        key = "value",
        key2 = "value2",
        key3 = "value3",
        key4 = "value4",
        key5 = "value5"
    }
    
    for k, v in pairs(t) do
        print(k, v)
    end
    

    Output:

    key2 value2
    key5 value5
    key value
    key4 value4
    key3 value3

    The output could be different. You can't guarantee that there will be order.

    So how do we make dictionaries go in order?

    Technically a dictionary won't be used. It will just be nested arrays in one big array.

    local arr = {
        {"key", "value"},
        {"key2", "value2"},
        {"key3", "value3"},
        {"key4", "value4"},
        {"key5", "value5"}
    }
    

    While a little bit of readability is lost, there is order.

    In addition, pairs(t) / next, t is arbitrary so you cannot guarantee order. So you should use ipairs(arr) or even a numeric for loop, just to guarantee order.

    local arr = {
        {"key", "value"},
        {"key2", "value2"},
        {"key3", "value3"},
        {"key4", "value4"},
        {"key5", "value5"}
    }
    
    for _, v in ipairs(arr) do
        print(v[1], v[2])
    end
    

    Output:

    key value
    key2 value2
    key3 value3
    key4 value4
    key5 value5


  • @sjr04Alt, but with this, you lose the functionality of indexing the dictionary with a string. You have to manually loop through the entire dictionary to find it. I don't think this is very useful at all. Not only that, but it's not really memory efficient, either.

  • Global Moderator

    @Phlegethon5778

    you lose the functionality of indexing the dictionary with a string. You have to manually loop through the entire dictionary to find it.

    Is there a reason you cannot use __index?

    but it's not really memory efficient, either.

    Why complain about efficiency? When we write inefficient code all the time?

    Take for example these two snippets that animate the transparency of a part

    for i = 0, 1, 0.1 do
        part.Transparency = i
        wait()
    end
    

    versus

    part.Transparency = 0
    wait()
    part.Transparency = 0.1
    wait()
    part.Transparency = 0.2
    wait()
    part.Transparency = 0.3
    wait()
    part.Transparency = 0.4
    wait()
    part.Transparency = 0.5
    wait()
    part.Transparency = 0.6
    wait()
    part.Transparency = 0.7
    wait()
    part.Transparency = 0.8
    wait()
    part.Transparency = 0.9
    wait()
    part.Transparency = 1
    

    If you guessed the first one, you're wrong. Loops add overhead. Heck, because of that it might be more efficient doing this

    arr[1], arr[2], ... arr[#arr]
    

    :\

    This is merely a tutorial of how to get order, it is not out there for efficiency and whatnot. You can optimise it if you wish


  • @sjr04Alt, sure, you could use __index, but it wouldn't be efficient. However, most of the people reading this who would want to use this kind of thing probably don't have a clue how to use metamethods.

  • Global Moderator

    Incapaz's solution is alright.

    However the __index metamethod would not help in any way.

    That being said, you can use a mixed table to enable random access while preserving the order of the elements:

    local t = {
        { key = "key1", value = "value1" },
        { key = "key2", value = "value2" },
        { key = "key3", value = "value3" },
        { key = "key4", value = "value4" },
        { key = "key5", value = "value5" }
    }
    
    for i = 1, #t do
        local pair = t[i]
        t[pair.key] = pair
    end
    
    -- ...
    
    -- iterating in order
    for _, pair in ipairs(t) do
        print(pair.key, ':', pair.value)
    end
    
    -- random access
    t["key2"].value = 2
    
    print(t["key2"].value)
    

    Output:

    key1 : value1
    key2 : value2
    key3 : value3
    key4 : value4
    key5 : value5
    2

Log in to reply
 

Looks like your connection to Scripting Helpers was lost, please wait while we try to reconnect.