--[[ @Author: Turbo - Holds a normal key/pair table and a index table counting from 1, the position of elements in the latter are ordered by the Z values defined via .add - Z value can be ommited in .add in which case the default value is used - elements can be gotten/removed either by normal key or index key - the indexIterator - keyIterator behave as ipairs - pairs SOME EXAMPLES: --LUA local elements = ISPriorityTable.new(); print(tostring(elements)); -- Key Value Zindex elements.add( "Key1", "test 1", 100 ); elements.add( 2, "test 2", 150 ); elements.add( "Key3", "test 3", 50 ); elements.add( "Key4", true, 75 ); elements.add( "Key5", "test 5" ); elements.remove("Key1"); elements.remove("Key3"); elements.remove("Key5"); elements.add("Key6", {"abcd","efgh"}, 100); print("elements size = "..tostring(#elements)); for index, value in elements.indexIterator() do -- note: the shortcut 'elements()' can be used instead of 'elements.indexIterator()' print(tostring(index).." : " ..tostring(value)); end print(""); for index = 1,#elements do print(tostring(index).." : " ..tostring(elements.getIndex(index))); end print(""); for key, value in elements.keyIterator() do print(tostring(key).." : " ..tostring(value)); end --LUAEND PRINTS: ISPriorityTable elements size = 3 1 : true 2 : table: 0073b140 3 : test 2 1 : true 2 : table: 0073b140 3 : test 2 2 : test 2 Key6 : table: 0073b140 Key4 : true --]] ISPriorityTable = {}; function ISPriorityTable.new() local function getElement(_key, _value, _zindex) local self = {}; self.key = _key; self.value = _value; self.zindex = _zindex; return self; end local name = "ISPriorityTable"; local array = {}; array.n = 0; local list = {}; local self = {}; local defaultZ = 1000; local function setElement( _k, _v, _z ) local e = list[ _k ]; if e and _v ~= nil then -- edit entry e.value = _v; else if e then -- remove entry local len,found = #array,false; for i = 1,len do if not found and array[ i ].key == _k then array[ i ] = nil; list[ _k ] = nil; array.n = array.n - 1; found = true; elseif found then array[ i-1 ] = array[ i ]; if i == len then array[ i ] = nil; end end end else -- add new entry e = getElement( _k, _v, _z ); for i = #array,0,-1 do if i == 0 or array[ i ].zindex <= _z then array[ i+1 ] = e; list[ _k ] = e; array.n = array.n + 1; return; end array[ i+1 ] = array[ i ]; end end end end function self.setDefaultZvalue( _z ) defaultZ = _z; end function self.add( _k, _v, _z ) local z = _z or defaultZ; setElement( _k, _v, z ); end function self.get( _k ) if list[ _k ] then return list[ _k ].value; end end function self.getIndex( _index ) if array[ _index ] then return array[ _index ].value; end end function self.remove( _k ) setElement( _k, nil ); end function self.removeIndex( _index ) local e = array[ _index ]; if e then setElement( e.key, nil ); end end function self.size() return #array; end function self.toString() return name; end function self.indexIterator() local index, count, e = 0, #array, nil; return function () index = index + 1; if index <= count then e = array[index]; return index, e.value, e.key; end end end function self.keyIterator() local k,e; return function () k,e = next(list, k); if e then return k, e.value; end end end -- metatable setmetatable( self, { __newindex = function( t, k, v ) end, __metatable = function( t ) end, __call = self.indexIterator, __tostring = self.toString, __len = self.size, }); return self; end