Ordered Table Simple

lua-users home
wiki

Difference (from revision 2 to current revision) (minor diff)

Changed: 1c1,2
== Ordered Table ==
A simple implemention of ordered table.
This is a different approach to the problem discussed in OrderedTable

Changed: 3c4,7
A simple implemention of ordered table
We don't use a nextindex table, since it takes to long to traverse compared to a
inassociative table holding the keys, also the table holding the keys is placed insided
the __index table for a fast lookup, in simple tests this method had a better benchmark
compared to the other, plus we can delete items via <this>:del( key )

Changed: 5c9
{{{!Lua
{{{!Lua

Changed: 11c15,19
metakeys can be seen with for i,k in <this>:ipairs() do
metakeys can be seen with for i,k in ( <this>:ipairs() or ipairs( <this>._korder ) ) do
ipairs( ) is a bit faster

variable names inside __index shouldn't be added, if so you must delete these again to access the metavariable
or change the metavariable names, except for the 'del' command. thats the reason why one cannot change its value

Removed: 15d22
mt._korder = {}

Added: 17a25,26
-- set key order table inside __index for faster lookup
_korder = {},

Changed: 19,35c28
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,
hidden = function() return pairs( mt.__index ) end,

Changed: 37,39c30
ipairs = function( self )
return ipairs( getmetatable( self )._korder )
end,
ipairs = function( self ) return ipairs( self._korder ) end,

Changed: 43,44c34,35
ordered = function( self )
local index = 0
opairs = function( self )
local i = 0

Changed: 46,48c37,41
index = index+1
local key = getmetatable( self )._korder[index]
if key then return key,self[key] end
i = i + 1
local k = self._korder[i]
if k then
return k,self[k]
end

Changed: 55c48,49
for i,k in self:ipairs() do
self[key] = nil
for i,k in ipairs( self._korder ) do

Changed: 57c51,52
table.remove( getmetatable( self )._korder, i )
table.remove( self._korder, i )
return

Removed: 60d54
self[key] = nil

Changed: 66,69c60,63
if not self[k] then
table.insert( getmetatable( self )._korder, k )
end
rawset( self,k,v )
if k ~= "del" and v then
rawset( self,k,v )
table.insert( self._korder, k )
end

Changed: 75,76c69,70
And the testcode
{{{!Lua
Testsuit:
{{{!Lua

Changed: 78,83c72,84
t["entry1"] = "value1"
t["entry2"] = "value2"
t["entry2"] = "value2upd"
t[3] = "three"
t[4] = "four"
print("PAIRS:")

t["a"] = "1"
t["ab"] = "2"
t["abc"] = "3"
t["abcd"] = "4"
t["abcde"] = "5"
t[1] = 6
t[2] = 7
t[3] = 8
t[4] = 9
t[5] = 10

print(">> t:pairs()")

Changed: 87c88
print("IPAIRS:")
print(">> t:ipairs()")

Changed: 91,92c92,93
print("ORDERED:")
for i,v in t:ordered() do
print(">> t:opairs()")
for i,v in t:opairs() do

Changed: 95,103c96,101
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(">> t:del( 3 )")
t:del( 3 )
print(">> t:del( \"abc\" )")
t:del( "abc" )
print(">> t:opairs()")
for i,v in t:opairs() do

Changed: 106,111c104,108
-- delete one entry
print("DELETING: new")
t:del( "new" )
print("PAIRS:")
for k,v in t:pairs() do
print( k,v )
print(">> t.abc = 11")
t.abc = 11
print(">> t:opairs()")
for i,v in t:opairs() do
print( i,v )

Changed: 113,114c110,115
print("ORDERED:")
for i,v in t:ordered() do
print(">> t.del = nil")
t.del = nil
print(">> t:del( 1 )")
t:del( 1 )
print(">> t:opairs()")
for i,v in t:opairs() do

Changed: 120,162c121,186
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
>> t:pairs()
1 6
2 7
3 8
4 9
a 1
ab 2
abcd 4
abcde 5
5 10
abc 3
>> t:ipairs()
1 a 1
2 ab 2
3 abc 3
4 abcd 4
5 abcde 5
6 1 6
7 2 7
8 3 8
9 4 9
10 5 10
>> t:opairs()
a 1
ab 2
abc 3
abcd 4
abcde 5
1 6
2 7
3 8
4 9
5 10
>> t:del( 3 )
>> t:del( "abc" )
>> t:opairs()
a 1
ab 2
abcd 4
abcde 5
1 6
2 7
4 9
5 10
>> t.abc = 11
>> t:opairs()
a 1
ab 2
abcd 4
abcde 5
1 6
2 7
4 9
5 10
abc 11
>> t.del = nil
>> t:del( 1 )
>> t:opairs()
a 1
ab 2
abcd 4
abcde 5
2 7
4 9
5 10
abc 11

Added: 163a188,194

== Other iterations, including iteration sorted by key ==

* OrderedTable
* SortedIteration
* SortedIterationSimple


A simple implemention of ordered table. This is a different approach to the problem discussed in OrderedTable

We don't use a nextindex table, since it takes to long to traverse compared to a inassociative table holding the keys, also the table holding the keys is placed insided the __index table for a fast lookup, in simple tests this method had a better benchmark compared to the other, plus we can delete items via <this>:del( key )

--[[
   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()  or ipairs( <this>._korder ) ) do
   ipairs( ) is a bit faster
   
   variable names inside __index shouldn't be added, if so you must delete these again to access the metavariable
   or change the metavariable names, except for the 'del' command. thats the reason why one cannot change its value
]]--
function newT( t )
   local mt = {}
   -- set methods
   mt.__index = {
      -- set key order table inside __index for faster lookup
      _korder = {},
      -- traversal of hidden values
      hidden = function() return pairs( mt.__index ) end,
      -- traversal of table ordered: returning index, key
      ipairs = function( self ) return ipairs( self._korder ) end,
      -- traversal of table
      pairs = function( self ) return pairs( self ) end,
      -- traversal of table ordered: returning key,value
      opairs = function( self )
         local i = 0
         local function iter( self )
            i = i + 1
            local k = self._korder[i]
            if k then
               return k,self[k]
            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
            self[key] = nil
            for i,k in ipairs( self._korder ) do
               if k == key then
                  table.remove( self._korder, i )
                  return
               end
            end
         end
      end,
   }
   -- set new index handling
   mt.__newindex = function( self,k,v )
      if k ~= "del" and v then
         rawset( self,k,v )
         table.insert( self._korder, k )
      end      
   end
   return setmetatable( t or {},mt )
end
-- CHILLCODE™
Testsuit:
t = newT()

t["a"] = "1"
t["ab"] = "2"
t["abc"] = "3"
t["abcd"] = "4"
t["abcde"] = "5"
t[1] = 6
t[2] = 7
t[3] = 8
t[4] = 9
t[5] = 10

print(">> t:pairs()")
for k,v in t:pairs() do
   print( k,v )
end
print(">> t:ipairs()")
for i,k in t:ipairs() do
   print( i,k,t[k] )
end
print(">> t:opairs()")
for i,v in t:opairs() do
   print( i,v )
end
print(">> t:del( 3 )")
t:del( 3 )
print(">> t:del( \"abc\" )")
t:del( "abc" )
print(">> t:opairs()")
for i,v in t:opairs() do
   print( i,v )
end
print(">> t.abc = 11")
t.abc = 11
print(">> t:opairs()")
for i,v in t:opairs() do
   print( i,v )
end
print(">> t.del = nil")
t.del = nil
print(">> t:del( 1 )")
t:del( 1 )
print(">> t:opairs()")
for i,v in t:opairs() do
   print( i,v )
end
Output:
>> t:pairs()
1       6
2       7
3       8
4       9
a       1
ab      2
abcd    4
abcde   5
5       10
abc     3
>> t:ipairs()
1       a       1
2       ab      2
3       abc     3
4       abcd    4
5       abcde   5
6       1       6
7       2       7
8       3       8
9       4       9
10      5       10
>> t:opairs()
a       1
ab      2
abc     3
abcd    4
abcde   5
1       6
2       7
3       8
4       9
5       10
>> t:del( 3 )
>> t:del( "abc" )
>> t:opairs()
a       1
ab      2
abcd    4
abcde   5
1       6
2       7
4       9
5       10
>> t.abc = 11
>> t:opairs()
a       1
ab      2
abcd    4
abcde   5
1       6
2       7
4       9
5       10
abc     11
>> t.del = nil
>> t:del( 1 )
>> t:opairs()
a       1
ab      2
abcd    4
abcde   5
2       7
4       9
5       10
abc     11

Other iterations, including iteration sorted by key


RecentChanges · preferences
edit · history
Last edited June 4, 2007 11:07 pm GMT (diff)