lua-users home
lua-l archive

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


The trouble with using table.remove is that it shifts down all the elements with indexes above the removed element. So it doesn't leave any holes but it will change indexes of many elements. This is probably not how you envisage an array to work.

Robert

----- Original Message -----
> From: "Sean Conner" <sean@conman.org>
> To: "Lua mailing list" <lua-l@lists.lua.org>
> Sent: Thursday, 26 September, 2013 10:06:21 PM
> Subject: Re: how to work with tables with holes
> 
> It was thus said that the Great Rafis Ganeyev once stated:
> > Tables can't be used so easily as array() in PHP. All Lua developers should
> > know their peculiarities to use them properly: distinctions between vector
> > and hash parts, no count() function, maybe vector and hash parts grew
> > strategy, etc.
> > 
> > My question is simple. If I have some collection of objects in vector part
> > and I create holes by setting nil to middle elements, length operator and
> > ipairs begin work improperly, how to I traverse this collection? Only with
> > pairs() or should I use table.getn(), which seems have been removed in Lua
> > 5.2? Or should I create element called "n" in hash part and create
> > add/remove functions for collection? What are best practices for that case?
> 
>   1) Don't set an element to nil.  Use table.remove() instead.  That way, #
>      will alway work:
> 
> 	t = { 1 , 2 , 3 , 4 }
> 	print(#t)
> 	table.remove(t,2)
> 	print(#t)
> 
>   2) Use a sentinel value to mark removal.
> 
> 	empty = {}
> 	t = { 1 , 2 , 3 , 4 }
> 	print(#t)
> 	t[2] = empty
> 	print(#t)
> 
> 	for i = 1 , #t do
> 	  if t[i] ~= empty then
> 	    print(t[i])
> 	  end
> 	end
> 
>   3) Keep track of both the size and the maximum index.
> 
> 	m = { __newindex = function(t,i,v)
> 			     if v == nil then
> 			       print(">>>")
> 			       t.N = t.N - 1
>                                t.P[i] = v
> 			       return
> 			     end
> 			     
> 			     if i > t.MAX then
> 			       t.MAX = i
> 			     end
> 
> 			     t.N = t.N + 1
> 			     t.P[i] = v
> 			   end
> 	}
> 	t = { P = { 1 , 2 , 3 , 4 } , N = 4 , MAX = 4 }
> 	setmetatable(t,m)
> 	print(t.N)
> 	t[2] = nil
> 	print(t.N)
> 
>   In my opintion, the best practice is #1.
> 
>   -spc
> 
> 
>