"Using # On a table without a array part is more likely a bug"

Hi developers,

I already have searched in some posts but i can’t find the solution (only in 1 post, but not the solution that i want) And i already have tried, but i never found the solution, but this is happening to me for some reason and i don’t know why, so here’s my script:

local Foods = {
	["Paulista"] = 10,
	["Nordestino"] = 30
}

script.Parent.MouseButton1Click:Connect(function()
	local plr = game.Players.LocalPlayer
	local leaderstats = plr:FindFirstChild("leaderstats").Cumidas
	leaderstats.Value = leaderstats.Value - 10
	local randomNumber = math.random(1, #Foods)
	local ChoiceKey = Foods[randomNumber]
end)

math.random(1, #Foods)

On this line, for some reason, it becomes a orange line on it for some reason, here’s what i mean:

Screenshot_9
And i want to resolve that, any help would be very appreciated.

Dictionaries do not support the # operator, because tables in Lua work differently than in other languages.

Basically, arrays and dictionaries are actually the same, but for arrays, the index (key) is automatically set for each value. For example, a table like {1,2,3} is actually {[1] = 1, [2] = 2, [3] = 3} under the hood.

And because of this, Lua can actually figure out how many elements are inside an array, because it’s automatically ordered. And that’s why the # operator only works on arrays. It can know how many elements are inside it.

But for dictionaries, it’s quite different. You set the index (key) yourself, Lua has no way of knowing what that key might be. And that’s why the # operator doesn’t work on them, it has no way of knowing how many elements are inside it because it cannot know which keys are inside the table.

Using a for loop would solve your case.

1 Like

Those explanations from this post originally. The accepted answer has more details.

so i think i’m forced to do that right:

local Foods = {
	[1] = 10,
	[2] = 30
}

script.Parent.MouseButton1Click:Connect(function()
	local gui = script.Parent.Parent.Parent
	gui:Destroy()
	local plr = game.Players.LocalPlayer
	local leaderstats = plr:FindFirstChild("leaderstats").Cumidas
	leaderstats.Value = leaderstats.Value - 10
	local randomNumber = math.random(1, #Foods)
	local ChoiceKey = Foods[randomNumber]
end)

You can just do
local Foods = {10, 30}

Or you can use a for loop that counts the amount of elements inside the dictionary.

local Foods = {
	["Paulista"] = 10,
	["Nordestino"] = 30
}

local count = 0
for _, v in Foods do
    count += 1
end

print(count) -- 2
1 Like

Ok, thanks, i will try that, thanks for the explanation tho!

1 Like

Just a last thing, i need to comment like that right?

10, -- Paulista
	30 -- Nordestino

(if i’m using the first thing of course)

If you’re using it like {10, 30}, then sure, you can use #Foods instead of the for loop.
But I don’t think that would really be convenient in the future, if you, for example, at one point want to work with the keys. Going with the answer that I gave you above would allow you to keep the dictionary structure. Though, it’s your choice.

i’m very confused now lol, i can’t choose

For your use case, using local Foods = {10, 30} would be better by looking at how you want to get a random value from the table in the first script.

Your code would be:

local Foods = {10, 30}

script.Parent.MouseButton1Click:Connect(function()
	local plr = game.Players.LocalPlayer
	local leaderstats = plr:FindFirstChild("leaderstats").Cumidas
	leaderstats.Value = leaderstats.Value - 10
	local randomNumber = math.random(1, #Foods)
	local ChoiceKey = Foods[randomNumber]
end)

I know but then i need 2 things, the name of the thingy and the value so i cant put only 1 value

Oh, then I misunderstood you I suppose. Check out the code I gave you below:

local Foods = {
	["Paulista"] = 10,
	["Nordestino"] = 30,
}

local function getRandomElement(tbl)
	local keys = {} -- Holds all the keys inside an array so they can be countable

	for index, _ in tbl do -- Goes through the dictionary to place the keys inside the array above
		table.insert(keys, index) -- Inserts the key in the keys array
	end

	local randomElement = tbl[keys[math.random(1, #keys)]] -- Selects a random element from the given dictionary using a random key from the keys array.

	return randomElement -- Returns the random element
end


script.Parent.MouseButton1Click:Connect(function()
	local plr = game.Players.LocalPlayer
	local leaderstats = plr:FindFirstChild("leaderstats").Cumidas
	leaderstats.Value = leaderstats.Value - 10
	
	local ChoiceKey = getRandomElement(Foods) -- Will be either 10 or 30
end)
1 Like

i’ll see it later, i need to lunch, but i’m sure it will work, so i will already mark it as solution

1 Like

Thanks, but how do i get the name?

Hello, are you here? I’m back from lunch, and yes, it worked

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.