lua-users home
lua-l archive

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


On Friday, July 22, 2011 02:38:14 AM Dirk Laurie wrote:
> On Fri, Jul 22, 2011 at 03:16:25AM +0200, Michelle Jenkins wrote:
> > I was told I should use multidimensional arrays as well as
> > tables. I don't know how to use either.

Michelle,

Everything Dirk writes below is true, and I think it's vital to add 
one thing. A table is an official Lua data type. An array is a computer 
science concept that *can be implemented* with a Lua table. Tables can 
also implement:

* Data dictionary/hash
* Data structures (like C struct)
* Database tables (in memory)
* OOP classes
* Stacks
* Queues

None of the preceding is actually a part of Lua, but all can be 
implemented using tables. So can arrays.

If I understand the situation correctly, Lua has exactly two types for 
complex data:

1) Tables
2) Metatables

All other complex data is built from those two and doesn't exist in 
the language.

The reason I believe it's important to be continuously aware of this 
distinction is forgetting it can break your heart. There was a long, 
long thread here about a year ago discussing what the value of 
#tablename should be. In a Lua table it's the highest consecutive 
integer key where the numeric keys start at 1. Everyone who thought of 
the construct as an "array" was horrified that it didn't bring up the 
actual number of items with integer keys, and they were horrified that 
there was no difference between mytable[5] = nil and simply not 
assigning anything to mytable[5]. Those who thought of it as a table 
used by the application programmer to implement an array had no 
problem with it, because that's how Lua tables work.

SteveT

> 
> All tables start like this:
> 
>     A={}    -- make a new empty table, different from all other
> tables
> 
> after which you can put anything in it (we say "assign a value")
> like this:
> 
>     A[1] = 10       -- a number
>     A[2] = 'abc'    -- a string
>     A[3] = {}       -- an empty table
>     A['abc'] = 2    -- the key into the table can be anything
> except nil A[3][1] = 42    -- A[3] is a table, right? So you can
> put anything in it. A.cde = A.abc   -- if the key is a name
> (letters and digits, starts -- with a letter, you may write it
> this way
> 
> An array is a table in which you have decided to use all the
> indices 1,2,3,...,m up to some value m called the "length" of the
> table.  If you haven't yet assigned a value to say A[7], its value
> is automatically `nil`.  If you have actually assigned non-nil
> values to A[1], A[2], ..., A[n] and you have not been using any
> other numbers as keys in A, Lua can figure out what m is from the
> table itself, this way:
> 
>     print(#A)       --> 3   (We've assigned up to A[3] and no more)
> 
> Otherwise it can't, and you have to remember m some other way, e.g.
> by saying `A.m=3`.  (Non-numeric keys don't spoil the array
> property.) It really can't, but it will try.  It will give you
> some number when you say `#A`, but don't believe that answer. It
> may be wrong.  (It may even be right, but don't bet on it.)
> 
> A two-dimensional array is a table in which each of those A[1] etc
> is a one-dimensional array which we call a "row".  Strictly
> speaking those arrays need not be the same length but most of the
> time it's convenient if they are, say n.  In that case we speak of
> an m by n array, and say it has m rows and n columns (although
> extracting a column as an array by itself takes some work).  Most
> of the time you want to assign something to every element of the
> array, e.g.
> 
>     function array1D (m,x)
>         -- make a new one-dimensional array with m elements
>         -- all equal to x
>         if x==nil then error("You may not make an array1D of nils")
> end local A={}
>         for i=1,m do A[i]=x end
>         return A
>         end
> 
>     function array2D (m,n,x)
>         -- make a new two-dimensional array with m rows and n
> columns -- in which every element equals x
>         if x==nil then error("You may not make an array2D of nils")
> end local A={}
>         for i=1,m do A[i]=array1D(n,x) end
>         return A
>         end
> 
> With a two-dimensional array, you must be careful that the rows are
> really different arrays.  This code does not work:
> 
>     function buggy_array2D (m,n,x)
>         -- tries make a new two-dimensional array with m rows and n
> columns -- in which every element equals x, but fails
>         return array1D(m,array1D(n,x))
>         end
> 
> Only one array of length n is created and it is assigned to every
> element. See:
> 
>     A = array2D(2,3,'a')
>     A[1][3] = 42
>     print(A[2][3]) --> a
>     B = buggy_array2D(2,3,'b')
>     B[1][3] = 42
>     print(B[2][3]) --> 42
> 
> Well, that's it for a start.  After this, better read the reference
> manual to find out where I have been economical with the truth.
> 
> Dirk

-- 
Steve Litt
Author: The Key to Everyday Excellence
http://www.troubleshooters.com/bookstore/key_excellence.htm
Twitter: http://www.twitter.com/stevelitt