Ordered Table Simple

lua-users home
wiki

Showing revision 2

Ordered Table

A simple implemention of ordered table

--[[
   LUA 5.1 compatible
   
   Ordered Table
   keys added will be also be stored in a metatable to recall the insertion oder
   metakeys can be seen with for i,k in <this>:ipairs() do
]]--
function newT( t )
   local mt = {}
   mt._korder = {}
   -- set methods
   mt.__index = {
      -- traversal of hidden values
      hidden = function( self )
         local mt = getmetatable( self )
         return pairs( mt.__index )
      end,
      -- print seen values
      print = function( self )
         for i,v in ipairs( self ) do
            print( i,v )
         end
      end,
      -- print hidden values
      printh = function( self )
         local mt = getmetatable( self )
         for k,v in pairs( mt.__index ) do
            print( k,v )
         end
      end,
      -- traversal of table ordered: returning index, key
      ipairs = function( self )
         return ipairs( getmetatable( self )._korder )
      end,
      -- traversal of table
      pairs = function( self ) return pairs( self ) end,
      -- traversal of table ordered: returning key,value
      ordered = function( self )
         local index = 0
         local function iter( self )
            index = index+1
            local key = getmetatable( self )._korder[index]
            if key then return key,self[key] end
         end
         return iter,self
      end,
      -- to be able to delete entries we must write a delete function
      del = function( self,key )
         if self[key] then
            for i,k in self:ipairs() do
               if k == key then
                  table.remove( getmetatable( self )._korder, i )
               end
            end
            self[key] = nil
         end
      end,
   }
   -- set new index handling
   mt.__newindex = function( self,k,v )
      if not self[k] then
         table.insert( getmetatable( self )._korder, k )
      end
      rawset( self,k,v )      
   end
   return setmetatable( t or {},mt )
end
-- CHILLCODE™
And the testcode
t = newT()
t["entry1"] = "value1"
t["entry2"] = "value2"
t["entry2"] = "value2upd"
t[3] = "three"
t[4] = "four"
print("PAIRS:")
for k,v in t:pairs() do
   print( k,v )
end
print("IPAIRS:")
for i,k in t:ipairs() do
   print( i,k,t[k] )
end
print("ORDERED:")
for i,v in t:ordered() do
   print( i,v )
end
print("TESTING DELETE FUNCTION")
t["new"] = "tmp"
t["new1"] = "tmp1"
print("PAIRS:")
for k,v in t:pairs() do
   print( k,v )
end
print("ORDERED:")
for i,v in t:ordered() do
   print( i,v )
end
-- delete one entry
print("DELETING: new")
t:del( "new" )
print("PAIRS:")
for k,v in t:pairs() do
   print( k,v )
end
print("ORDERED:")
for i,v in t:ordered() do
   print( i,v )
end
Output:
PAIRS:
4       four
entry2  value2upd
3       three
entry1  value1
IPAIRS:
1       entry1  value1
2       entry2  value2upd
3       3       three
4       4       four
ORDERED:
entry1  value1
entry2  value2upd
3       three
4       four
TESTING DELETE FUNCTION
PAIRS:
entry2  value2upd
new1    tmp1
new     tmp
3       three
4       four
entry1  value1
ORDERED:
entry1  value1
entry2  value2upd
3       three
4       four
new     tmp
new1    tmp1
DELETING: new
PAIRS:
entry2  value2upd
new1    tmp1
3       three
4       four
entry1  value1
ORDERED:
entry1  value1
entry2  value2upd
3       three
4       four
new1    tmp1

RecentChanges · preferences
edit · history · current revision
Edited June 2, 2007 6:53 pm GMT (diff)