Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do I get a random number from a dictionary?

With a normal table, you could just do;

local t = {"red", "blue"}
print(math.random(1, #t))

and it will work. But in a dictionary, it doesn't.

local t = {red = 0, blue = 0}
print(math.random(1, #t)) -->bad argument #2 to 'random' (interval is empty)

Doing further tests shows that the table doesn't even have a length, which doesn't really make sense.

local t = {red = 0, blue = 0}
print(#t) --> 0

Of course, I could do something like:

local t = {red = 0, blue = 0}
local rand = math.random(1,2)
if rand == 1 then
	print("red was chosen")
else
	print("blue was chosen")
end

but this is really messy once the table gets any bigger.

Is there any way I can choose a random number from a dictionary efficiently?

2 answers

✓ Accepted answer

The # operator tells you how many elements can be indexed by going list[1], list[2], ..., list[#list].

That means if there isn't something at [1], # is going to answer with 0

How would having a length of 2 for {red = 5, blue = 7} be helpful, ever? It doesn't tell you where to find anything in the list, or really much anything else about the list -- and it would cause things that use # to completely mess up.


The most straight forward way to select a random element from a dictionary is to make a list of all of the keys, and then pick a random key from that list:

local t = {red = 0, blue = 0}

local keys = {}
for key, _ in pairs(t) do
	table.insert(keys, key)
end

local randomKey = keys[math.random(#keys)]

print("Random key: ", randomKey)
print("Thing there: ", t[ randomKey ] )

You can then just ask what's at that random key to get a random value.

3 comments

0

Or you could go 't[keys[math.random(1,#keys)]]' c:

0

Yes, but it's more illustrative of the point to give the values names

0

Gracias senor!

What you could do is take advantage of hash-table lookup by just making an array of the table's keys. This is just a matter of using what you already know to solve a problem you think you haven't encountered quite yet.

For example...

local t = {red = 0, blue = 0} -- original table

local index 	= 1
local keys 	= { } -- array of table keys
for key, _ in next, t do -- iterate through all key-value pairs
	keys[index] 	= key -- add to key array
	index 			= index + 1
end

Then, it's just a matter of getting a random key from an array.

local randomKey 	= keys[math.random(#keys)]
local randomValue 	= t[randomKey]

Just keep in mind that even if a method may look bad, if you can't find any better solution with the resources you have it must be the best one available to you even if you don't like it. After all, completing a task is better than never completing it at all...

This discussion is preserved as it was. New answers, comments, and votes are closed.