How to randomise an item from a dictionary

I am trying to get a random value, either a banana, or chocolate and its data inside (Forget soap). If I try table[math.random(1, #table] an error appears: ‘invalid argument #2 to ‘random’ (interval is empty)’.
How could I fix this?

That’s because you can’t get the length of a dictionary. I’d approach it like this:

local food = {
    {
        ['Name'] = 'Banana';
        ['Amount'] = 12;
    };
    {
        ['Name'] = 'Chocolate';
        ['Amount'] = 6;
    };
}

So there are no feasible way to get an item from a dictionary? Except from re-arranging.

local Food = {
	["Banana"] = {
		["Amount"] = 12
	},
	["Chocolate"] = {
		["Amount"] = 6
	}
}

local FoodNames = {
	"Banana",
	"Chocolate"
}

local randNum = math.random(1, #FoodNames)
local randFoodName = FoodNames[randNum]
local randFood = Food[randFoodName]
for i, v in pairs(randFood) do
	print(i, v)
end

Store the names of the foods in an array, then grab a random food from that array and use it to index the original dictionary named “Food”.

Shortened version:

local Food = {
	["Banana"] = {
		["Amount"] = 12
	},
	["Chocolate"] = {
		["Amount"] = 6
	}
}

local FoodNames = {
	"Banana",
	"Chocolate"
}

local randFood = Food[FoodNames[math.random(1, #FoodNames)]]
print("Amount "..randFood["Amount"])

You might be able to do this, it’s probably going to be slower though:

local food = {
    ['Banana'] = {
        ['Amount'] = 12;
    };
    --continue for the rest of the table
}
local function getRandomFromDictionary(dictionary)
    local indexes = {} -- table of all indexes in the dictionary
    for i,v in pairs(dictionary) do -- insert all of the indexes into the table
        indexes[#indexes + 1] = i
    end
    return dictionary[indexes[math.random(1,#indexes)] -- return a random entry from the table of indexes
end

I"ll try these solutions, thank you.

Screen Shot 2021-11-15 at 11.06.17 PM
The function only prints the amount, is there a way to print the table’s name the amount is contained in? (Banana)

You could return the index and the value,

-- inside the getRandomFromDictionary function,
local randomIndex = indexes[math.random(1,#indexes)]
return randomIndex, dictionary[randomIndex]
-- ...
-- then when calling the function,
local index, value = getRandomFromDictionary(food)
-- index would be Banana for example, value would be the table with the amount

Or, you could just return the index and index the table as you need it,

-- inside the getRandomFromDictionary function,
return indexes[math.random(1,#indexes)]
-- ...
local randomIndex = getRandomFromDictionary(food)
-- randomIndex would be banana, then to index it do,
local infoTable = food[randomIndex]
2 Likes

That worked, thanks for the help

1 Like