How can I distinguish a table from a dictionary in my script?

Hello!

I am currently working on a crate system on my game. I want to create a function that returns a random item within a table. The thing is that since I would just use the length of the table and return a random value. The problem is that you can’t get the length of the dictionary so how would I go about discerning the difference between the two inside of a script?

Using type and typeof both return ‘table’, regardless of whether it’s a dictionary or table.

2 Likes

Why not just return a random key from the dictionary? You can do like a count function and use the returned number as number max.

2 Likes

Never thought of that actually, that’s a good idea. Thanks!

2 Likes

Just a quick heads up if you don’t be know what’s a count function:

local function ReturnCount(Table)
    local count = 0
    for _,_ in pairs(Table) do
        count += 1
    end
    return count

Correct me if I’m wrong but, the for loop should yield the code until everything is being indexed in the table and will return the count.

1 Like

I was planning on doing something closer to this, avoids the need of a count function.

    ChooseRandomFromArray = function(self, array)
		local indexes = {}
		for i,v in pairs(array) do
			indexes[#indexes + 1] = i
		end
		
		local chosenNumber = math.random(1, #indexes)
		local chosenIndex = indexes[chosenNumber]
		
		return array[chosenIndex]
	end;

Yeah it still works, I think it’s a bit more complicated than mine but still works. I’m pretty sure you can index dictionary, can’t you?

Yeah, you can index dictionaries. The problem I was facing is that you can’t get the length of dictionaries. Pairs goes through the entire dictionary whereas ipairs stops if there’s a numerical index missing.

Basically the only difference between a dictionary and a table is that tables’ indexes are always numeric whereas dictionaries have other indexes. Pretty much identical in terms of structure.

local table = {
    [1] = 'this';
    [2] = 'is';
    [3] = 'a';
    [4] = 'table';
}

local dictionary = {
    ['this'] = 'is';
    ['a'] = 'dictionary';
}
1 Like

Just to answer OP’s question, the best way to distinguish between an array and a dictionary that I can think of would be to iterate over the given table and check the index’s type.

local function GetTableType(t)
	assert(type(t) == "table", "Supplied argument is not a table")
	for i,_ in pairs(t) do
		if type(i) ~= "number" then
			return "dictionary"
		end
	end
	return "array"
end


local table1 = GetTableType({
	[1] = "Test"
})

local table2 = GetTableType({
	["1"] = "Test"
})

print(table1)
print(table2)
-- array
-- dictionary

2 Likes