Question

Say I have this dictionary in Lua

places = {dest1 = 10, dest2 = 20, dest3 = 30}

In my program I check if the dictionary has met my size limit in this case 3, how do I push the oldest key/value pair out of the dictionary and add a new one?

places["newdest"] = 50

--places should now look like this, dest3 pushed off and newdest added and dictionary has kept its size

places = {newdest = 50, dest1 = 10, dest2 = 20}
Was it helpful?

Solution

It's not too difficult to do this, if you really needed it, and it's easily reusable as well.

local function ld_next(t, i) -- This is an ordered iterator, oldest first.
  if i <= #t then
    return i + 1, t[i], t[t[i]]
  end
end

local limited_dict = {__newindex = function(t,k,v)
  if #t == t[0] then -- Pop the last entry.
    t[table.remove(t, 1)] = nil
  end
  table.insert(t, k)
  rawset(t, k, v)
end, __pairs = function(t)
  return ld_next, t, 1
end}

local t = setmetatable({[0] = 3}, limited_dict)

t['dest1'] = 10
t['dest2'] = 20
t['dest3'] = 30
t['dest4'] = 50

for i, k, v in pairs(t) do print(k, v) end
dest2   20
dest3   30
dest4   50

The order is stored in the numeric indices, with the 0th index indicating the limit of unique keys that the table can have.

OTHER TIPS

Given that dictionary keys do not save their entered position, I wrote something that should be able to help you accomplish what you want, regardless.

function push_old(t, k, v)
  local z = fifo[1]
  t[z] = nil
  t[k] = v
  table.insert(fifo, k)
  table.remove(fifo, 1)
end

You would need to create the fifo table first, based on the order you entered the keys (for instance, fifo = {"dest3", "dest2", "dest1"}, based on your post, from first entered to last entered), then use:

push_old(places, "newdest", 50)

and the function will do the work. Happy holidays!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top