#table returns 0

I have a table + dictionaries in it, and it just returns 0, what’s the issue?

local icons = {

	a = 1;
	b = 2;

	Common = {
		"rbxassetid://5069961595";
	};
	["Rare"] = {
		"rbxassetid://5069962024";
	};
	["Epic"] = {
		"rbxassetid://5069961746";
	};
	["Legendary"] = {
		"rbxassetid://5069961928";
	};
	["Exotic"] = {
		"rbxassetid://5069961848";
	};

}

print(#icons)

Outputs:
0

3 Likes

The # operator only gets the length of the table’s array part. So you’ll need something like

local function len(t)
    local n = 0
    
    for _ in pairs(t) do
        n = n + 1
    end
    return n
end
7 Likes

That’s alright, works for me!

get this to 30 characters

1 Like

Also, I need to get one of the images from within the table, so I want to choose a random rarity, and random image within that rarity, this is what I currently have but it errors cause I can’t really think of a way…

local icons = {

	Common = {
		"rbxassetid://5069961595";
	};
	Rare = {
		"rbxassetid://5069962024";
	};
	Epic = {
		"rbxassetid://5069961746";
	};
	Legendary = {
		"rbxassetid://5069961928";
	};
	Exotic = {
		"rbxassetid://5069961848";
	};

}
			local n = rand:NextInteger(1,len(icons))
			print(n)
			print(icons[n])
			local img = rand:NextInteger(1,icons[n])
			print(img)
			icon.Image = img

Players.Korrow.PlayerGui.ScreenGui.LocalScript:69: attempt to get length of a nil value
line 69: print(icons[n])

local probability = {	-- Change the 'Chance' variable to the desired probability
	{Type = "Common",    Chance = 1};
	{Type = "Rare",      Chance = 0.2};
	{Type = "Epic",      Chance = 0.1};
	{Type = "Legendary", Chance = 0.03};
	{Type = "Exotic",    Chance = 0.01};
}

local loot = {
	Common = {
		"rbxassetid://5069961595";
	};
	Rare = {
		"rbxassetid://5069962024";
	};
	Epic = {
		"rbxassetid://5069961746";
	};
	Legendary = {
		"rbxassetid://5069961928";
	};
	Exotic = {
		"rbxassetid://5069961848";
	};
}

local function reverse(t)
	for i = 1, math.floor(#t/2) do
	   local j = #t - i + 1
	    t[i], t[j] = t[j], t[i]
	end
	return t
end

local function getType(buff, RNG)
	local rarity = math.min(RNG:NextNumber() + buff, 1)
	local items  = { }
	for i, v in next, probability do
		if v.Chance >= rarity then
			table.insert(items, v)
		end
	end
	
	return reverse(items)[1]
end

local function getLoot(buff)
	-- 'buff' to decrease odds of rarer items being present
	local RNG = Random.new()
	     buff = buff or 0
		 
	local item = getType(buff, RNG)
	return loot[item.Type][RNG:NextInteger(1, #loot[item.Type])]
end

table.foreach(getLoot(), print)
1 Like

Wasn’t looking for the whole schematic for a random drop system but that’ll do! :joy:

Glad that provided you with the solution.

Let me know if there’s anything you don’t understand.

1 Like

What does foreach do?

eeeeeeeeeeeee

table.foreach is just is just a table iterator, similar to next or pairs, you pass it a function to enact with each table pair (index, value). I used it in that script just to print the results of the loot for you to see how it works - it’s actually a deprecated function as of Lua 5.1, only recommended for printing to output.

Just do:

local new_loot = getLoot()

1 Like

I don’t know if this is a cause to re-write everything, but if I were to now - add a list of items to each rarity, how would I go for it?

  • Also to pick a random item within that rarity.
local loot = {
	Common = {
		["Item1"] = {
			name = "Common";
			icon = "rbxassetid://5069961595";
		}
	};
	Rare = {
		["Item1"] = {
			name = "Rare";
			icon = "rbxassetid://5069962024";
		}
	};
	Epic = {
		["Item1"] = {
			name = "Epic";
			icon = "rbxassetid://5069961746";
		}	
	};
	Legendary = {
		["Item1"] = {
			name = "Legendary";
			icon = "rbxassetid://5069961928";
		}
	};
	Exotic = {
		["Item1"] = {
			name = "Exotic";
			icon = "rbxassetid://5069961848";
		}
	};
}

Example Table.

So if you want to continue using the script I sent you above, then you’d need to modify your table like so:

local loot = {
	Common = {
		{name = "Item1", rarity = "common", icon = "some_ref"},
		{name = "Item2", rarity = "common", icon = "some_ref"},
		{name = "Item3", rarity = "common", icon = "some_ref"}
	};
	Rare = {
		{name = "Item1", rarity = "rare", icon = "some_ref"}
	};
	Epic = {
		{name = "Item1", rarity = "epic", icon = "some_ref"}
	};
	Legendary = {
		{name = "Item1", rarity = "legendary", icon = "some_ref"}
	};
	Exotic = {
		{name = "Item1", rarity = "exotic", icon = "some_ref"},
		{name = "Item2", rarity = "exotic", icon = "some_ref"}
	};
}

The reason being is how I selected the random object within that rarity class, I used a [number] index reference, you can’t select it by a string key randomly unless you built a function to do so.

1 Like

Okay, so how can I get the properties of the item?
I tried this and it works:

			local imgLoot = getLoot()
			for i,v in pairs(imgLoot) do -- IS THIS AN EFFICIENT WAY?
				if i == "icon" then
					icon.Image = v
				end
			end
			icon.Image = imgLoot[icon] -- THIS DOES NOT WORK.

Also don’t want to have to iterate through it every time…

Please read this link so you better understand tables

You’re refering the imgLoot array with a variable ‘icon’, which I imagine hasn’t been defined as a string value of ‘icon’. This means that you’re effectively referencing imgLoot[nil], or from your application, looks like you’re referencing the imgLoot table with the ImageLabel object… You would need to do one of the following:

icon.Image = imgLoot.icon

-- or

icon.Image = imgLoot['icon']
1 Like

I agree my questions are naive and I make these small mistakes :sweat_smile:
But I appreciate your help!

FYI: If you wanted a metatable approach then you could achieve this with the __len metamethod, __len is invoked when the # operator is used.

For example:

local Dictionary = setmetatable({
    A = 1;
    B = 2;
}, {
    __len = function(self) --// Function will be equivalent to incapaz's len function
        local Count = 0;

        for _ in pairs(self) do --// self is the actual table
            Count = Count + 1;
        end

        return Count;
    end
});

print(#Dictionary); --// 2