remove multiple values from indexed table

Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

Re: remove multiple values from indexed table

Post by Caled »

I could have sworn that the code you gave me, Denarii, was working (well) for several months. Yesterday I noticed that it doesn't work as I thought that it does. :removeall does remove everything, but the indexes will not be readjusted to be sequential. (If it hasn't been working all this time, which is most likely, it probably explains why I've had so much trouble killing people in duels :oops: - my fault for not testing it properly 5 months ago)

I'm wrote the following now instead, which is working for me, but I haven't figured out how to put it into your metatable thingy (which makes for a nicer syntax). Still, this is working for me so I am happy, but I thought I ought to share it:
Code: [show] | [select all] lua
itable = {}

function itable.remove(t,n)
	local temp = {}
	local n = tonumber(n)
	local newcount = 0
	for num,val in ipairs(t) do
		if num ~= n then 
			newcount = newcount + 1
			temp[newcount] = val
		end
	end
	return temp
end

function itable.removeall(t,v)
	local temp = {}
	local newcount = 0
	for _,val in ipairs(t) do
		if val ~= v then
			newcount = newcount + 1
			temp[newcount] = val
		end
	end
	return temp
end

temptable = {"item1", "item2", "item3", "item2",}
--temptable = itable.remove(temptable,2)
temptable = itable.removeall(temptable,"item2")
display(temptable)

Denarii
Posts: 111
Joined: Thu Dec 03, 2009 10:54 pm

Re: remove multiple values from indexed table

Post by Denarii »

Try this:
Code: [show] | [select all] lua
function IITable()
    return setmetatable({
        __keyindex = {},

        removeall = function(self, value)
            for k in pairs(self.__keyindex[value]) do
                if k == "remove" or k == "removeall" or k == "__keyindex" then return false end
                if type(k) == 'number' then
                    table.remove(self, k)
                else
                    self[k] = nil
                end
                self.__keyindex[value] = nil
            end
        end,

        remove = function(self, key)
            local v = self[key]
            if v == "remove" or v == "removeall" or v == "__keyindex" then return false end
            if type(key) == 'number' then
                table.remove(self, key)
            else
                self[key] = nil
            end
            self.__keyindex[v][key] = nil
        end,
    }, {
        __newindex = function(t, key, value)
            if type(t) == "table" then
                local v = rawget(t, key)
                
                rawset(t, key, value)
                
                if value ~= nil then
                    if rawget(t.__keyindex, value) then
                        t.__keyindex[value][key] = true
                    else
                        t.__keyindex[value] = { [key] = true }
                    end
                end
                
                return
            end
        end,
    })
end

test = IITable()

test[1] = "test"
test[2] = "test"
test[3] = "test"

display(test)

test:remove(2)

display(test)

test:removeall("test")

display(test)

Post Reply