Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

tables

edited January 2012 in General Posts: 168

if i have a table:

table[1] = value1
table[2] = value2
table[3] = value3

and i remove table[2],

table[2] = nil

does it look like this:

table[1] = value1
table[2] = value3

or like this:

table[1] = value1
table[3] = value3

?

the actual question is, do the values change position after the position behind is deleted?

Tagged:

Comments

  • edited January 2012 Posts: 273

    I don't know but I just tried it using the online interpreter here: http://repl.it/

    Setting table[2]=nil works as you suggest (i.e. table[3] contains value3) but doesn't play nice (at least in my short tests) with ipairs() -- the iterator stops after table[1] -- nor with the table length function -- print(#table) returns 1 -- but I suggest you try it and see for yourself.

    If you use table.remove(table,2) and iterate through the table with ipairs() you will get:

    table[1] = value1
    table[2] = value3
    
  • Posts: 2,161

    ipairs starts at 1 and keeps going until table[i] evaluates to nil. So in this example, it stops at 1. You still get everything with pairs, but not necessarily in the right order. If you want everything to stay sequential then you have to use table.remove(table,2) as that shifts everything down after removing the element (this will "cost" a little processing time, of course).

  • edited January 2012 Posts: 273

    Oh good to know. Thanks.

    Edit: is this the same reason that the table length operator (here #table) stops at 1 too?

    Edit 2: Found the answer here:

    If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).
    

    Section 2.5.5 http://www.lua.org/manual/5.1/manual.html

  • BortelsBortels Mod
    edited January 2012 Posts: 1,557

    Yes - this is why the table length function stops, exactly so.

    I find it helpful to simply think of an 'array', or a 'hash' - they're both tables, but by using a given table exclusively as an array or a hash, the confusion dies down.

    The array is simply a sparse array - if you want length, keep track of it yourself.

    if it's a hash, "ipairs" is simply invalid. Use "pairs", and if you want it sorted... sort it, hashes are inherently unordered.

    if you want an ordered hash, or anything more complex - make a class() and wrap up the details of your implementation. :-)

  • Posts: 273

    Thanks. I must confess that I'm not familiar with the technical difference between an array and a hash. But I am learning...

    (And here in Holland hash has rather other usage.)

  • BortelsBortels Mod
    Posts: 1,557

    those are perl words. Basically, an array is a group of items indexed by a number. A Hash is a group of items indexed by a key, which is usually a string. In other languages, they'll call that a "map".

    key difference is the key - in an array, the key is an integer, usually starting with 0 (but 1 in lua!), and you don't usually have holes (a sparse array). With a hash, the key is anything you want. A lua table is a hash or a map. A lua "array" is simply a table where you've promised yourself the keys will all be integers - consecutive integers if you want the #length function to work.

  • Posts: 2,161

    Although, to be precise, a lua table is both a hash and an array. It has an array part and a hash part and so it has the "best of both worlds" in that the array part is optimised for being an array and the hash part for being a hash. So table[1] and table["1"] are both legal in the same table but refer to different terms as the first is in the array part and the second in the hash.

  • edited January 2012 Posts: 273

    Ah Mr. Bortels thank you. I've always been attracted to perl -- at least from a distance (why? I don't know exactly... but I suspect it has something to do with how monkish and arcane the code looks or the fact that it is often used to do the sort of things that interest me).

    The thought that hash and array are perl terms will definitely help me remember the distinction you've made.

  • edited January 2012 Posts: 273

    @Andrew ah, precision makes it all curiouser and curiouser.

  • BortelsBortels Mod
    Posts: 1,557

    Mmmm.... Andrew, are you sure the array part is optimized for being an array? I suspect that's not the case; an optimal array is a table of pointers, so lookup is fixed time. I suspect a lua table is always hashed key access. If that wasn't the case, the length would be a simple size calculation, rather than the iteration thru the table that it is. The fact that you can mix integer and string keys tells me it's not an optimal array... Where in a key table is "dog" as a key, and how would you handle a bucket collision? I'm pretty it's simply a non-optimized table underneath.

    I could look at the lua source to confirm, but I'm too damned lazy. (I'm sick today, at home in bed)

  • Posts: 2,161

    Okay, I don't know about the "optimised" bit. But there are definitely two parts. I got my information from http://www.lua.org/gems/sample.pdf. Well worth reading.

  • BortelsBortels Mod
    Posts: 1,557

    I stand corrected! That's an interesting document - it also mentions the causes behind some of the performance issues around string manipulations in a loop. I may need to buy the book.

    So - Andrew's right; if you keep your keys to integers 0-n, and you go consecutively, you should have array-like (not hash-like) performance. A pleasant surprise!

    I don't mind being wrong, especially when it turns out I was pessimistic. :-)

  • Ive tried it Out, in an app called"luabox" and there the output was:

    table[1] = value1
    table[2] = Nil
    table[3] = value3
    

    Yipiiieee :)

  • edited January 2012 Posts: 273

    @Maxiking16 Glad you got what you wanted. And thanks for asking the question... I've definitely learned something because you did.

Sign In or Register to comment.