Table does not want to remove a dictionary by using table.remove()

Code (VotingList is used as an example):

local VotingList = {
	["MILLENNlA"] = 1
}

local VotingListCopy = VotingList
local TopThree = {}
repeat
	local MostVotesPerCircle = nil
	local HighestVote = 0
	local index = 0
	for candidate,votes in pairs(VotingListCopy) do
		if votes >= HighestVote then
			HighestVote = votes
			MostVotesPerCircle = candidate
		end
		index += 1
	end
	TopThree[MostVotesPerCircle] = HighestVote
	table.remove(VotingListCopy, index)
	print("removed")
until #TopThree == 3 or #VotingListCopy == 0
print("Copy: ",VotingListCopy)
print("Top three: ",TopThree)

It goes through all the lines without any issues, even prints out “removed”, but in the end, the dictionary from the table hasn’t been removed.
image

Dictionaries aren’t indexed the same way arrays are. The way you have it set up, to remove “MILLENNlA”, you’d have to do

VotingList["MILLENlA"] = nil

Instead of making index a number, you could make it the candidate. Something like this should work:

local VotingList = {
	["MILLENNlA"] = 1
}

local VotingListCopy = VotingList
	local TopThree = {}
	repeat
		local MostVotesPerCircle = nil
		local HighestVote = 0
		for candidate,votes in pairs(VotingListCopy) do
			if votes >= HighestVote then
				HighestVote = votes
				MostVotesPerCircle = candidate
			end
		end
		TopThree[MostVotesPerCircle] = HighestVote
		-- table.remove(VotingListCopy, index)
        VotingListCopy[MostVotesPerCircle] = nil
		print("removed")
	until #TopThree == 3 or #VotingListCopy == 0
	print("Copy: ",VotingListCopy)
	print("Top three: ",TopThree)

Now that I think about it, this “until” condition wouldn’t break using #TopThree == 3 or #VotingListCopy because you can’t use # to get the length of a dictionary. It will always return 0.

So, should I rather iterate through the whole table and perhaps do some sort of a timer? Or is there a better way?

Also, that worked! Thanks.

It depends exactly what you’re using this code for. Contextually, it just seems to be getting the top 3 votes from a given dictionary of responses. What do you mean a ‘timer’? We can move it to DMs if you want so we don’t keep bumping the thread, or reply here. Either works :+1:

1 Like
local VotingList = {{"MILLENNlA", 1}, {"Player1", 0}} --Array of arrays makes the # operator usable.

local VotingListCopy = VotingList --This doesn't make a copy of the table (just points to the same table value).
local TopThree = {}

repeat
	local MostVotesPerCircle = nil
	local HighestVote = 0
	local VoterIndex = 0
	for Index, PlayerVotesArray in ipairs(VotingListCopy) do
		for Username, Votes in ipairs(PlayerVotesArray) do
			if Votes >= HighestVote then
				HighestVote = Votes
				MostVotesPerCircle = Username
				VoterIndex = Index
			end
		end
	end
	TopThree[#TopThree + 1] = {MostVotesPerCircle, HighestVote}
	table.remove(VotingListCopy, VoterIndex)
until #TopThree == 3 or #VotingListCopy == 0

Here’s a rewrite of your script with everything converted into arrays such that the various table library functions and the length operator can be used.

Just be aware that you can’t copy tables by assigning variables which point to/refer to tables to other variables, take the following for example.

local table1 = {1, 2, 3}
local table2 = table1
print(table1, table2)

This is the output of the above script.

image

Both variables point to/refer to the same table value, what you’re seeing in that output is the address in memory at which the table is located/situated.

If you want to copy a table value you could do something similar to the following.

local table1 = {1, 2, 3}
local table2 = {table.unpack(table1)}
print(table1, table2)

The output of the above script.

image

As you can see the addresses in memory are different which means you have two unique table values (even though they store/hold the same data).

1 Like