lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

A simple idea crossed my mind and I thought some of you might enjoy,
so I decided to share.

After a number of times when I had to iterate arrays, mark some
elements for removal, and then remove them in a second loop, I wished
I'd be able to do it in one go. Doing it "by hand" with a while loop
managing the index variable explicitly sounded cumbersome, so it
occured to me I could write a custom iterator instead.

ipairs_remove returns the index and value as usual, plus a "remove"
function that removes the current element from the array and adjusts
the iteration so it keeps going (if you table.remove() the current
element during an ipairs iteration, you end up skipping the next
item). It never occured to me before to return a utility function like
this through the iterator; it seems an elegant solution.

Have fun!

function ipairs_remove(tbl)
   local i = 0
   local remove = function()
      table.remove(tbl, i)
      i = i - 1
   end
   return function()
      i = i + 1
      if tbl[i] then
         return i, tbl[i], remove
      end
      return nil
   end
end

local t = { "a", "b", "c", "d", "e" }

for i, t, remove in ipairs_remove(t) do
   print(i, v)
   if v == "c" then remove() end
end

print("** After removal: **")

for i, v in ipairs(t) do
   print(i, v)
end

-- Hisham