Number of items in table appearing as 0 - invalid argument #2 to 'random' (interval is empty)

I have a module script set-up in ReplicatedStorage somewhat like this:

local Menu = {

    Mains = {
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
    };

    Drinks = {
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
        MenuItemHere = {Name = "eeee", Price = 1.111;};
    }

}

return Menu

Iā€™m requiring this module script from a ServerScript and Iā€™m trying to get the number of items that are in the Menu.Mains table and Menu.Drinks table, so I do this:

local Menu = require(ReplicatedStorage.Menu) -- require the module script

function ThisIsAFunction()
    local Courses = Menu.Mains
    local RandomCourse = Courses[math.random(1 #Courses)] -- error: invalid argument #2 to 'random' (interval is empty)  
    -- this error is happening because '#Courses' = 0. but how?

    print(Courses) -- prints a table just like the module script - perfectly fine
    print(#Courses) -- prints '0'
    -- how is this printing '0' when there is clearly more than 0 items in the table?
end

Why/How is #Courses equal to 0 when there is clearly items in the dictionary.

The length operator does not account for entries with non-numeric keys/indices. If you wanted a proper count, you would loop through the table using the pairs iterator in a for loop and count each entry you iterate over.

Your dictionary can be transformed into an array for which the values can be accounted for by the length operator:

local Menu = {
    Mains = {
        { name = "Main1", price = 1; item = item1 },
        { name = "Main2", price = 2; item = item2 },
        { name = "Main3", price = 3; item = item3 }
    },

    Drinks = {
        -- you get the gist
    }
}
2 Likes

table.getn(table) would be valid too.

Valid in what way, exactly? Sure, it returns the amount of entries in the table just like # but it faces the same issue with #: it only counts entries that are indexed by integers (i.e: only array-like entries) and assuming there are no holes and it also expects an array as an argument so using table.getn still yields 0 as the result for dictionaries

If you mean to count entries indexed by integers, then that also works ā€“ just preference whether to use # or table.getn

Valid for your conversion of the dictionary into an array.

I already tried that as an alternative. It has the same output. @Rare_tendoā€™s solution worked

Hence I stated.

would be valid too.

1 Like