Page 1 of 2

Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 4:50 am
by Bowlman
I seem to have problem to use right table store method. Or I just cant figure out the best way to use it. Or them. So I want to store 10 images and all those 10 images have 10 frames (they are on they own images as well. I want to put them in table and I want to call them with numerical index. Because I want to call them easy and quickly in loop. So I have Image1-1, Image 1-2 ... Image 1-18. And then Image 2-1, Image 1-2... Im used to use two dimentional arrays so I could call them either by images or by frame. This is from another language I have used to use:

Dim Image(10, 18) -- setting the table
--load pictures with two index, image and frame
--could be done with double loop or one by one. As needed.
for t = 1 to 10
for tt = 1 to 18
--Here i could call any frame from every picture. And later on I could control all the frames by knowing the index (picture and the frame of the picture
next tt
next t

So how I would do something like this in Love2D. I know the basic commands for loading pictures etc, but the idea of a bit different kind of tables got me stuck. Its so easy call numbers from the index. Its like a big grid when you have number when you put something in and same number when you take something out. Easy to understand. But here many times its about name as index and I dont feel like its clear every times what you are calling and from where. I think I might be a bit off course and there must be really easy to understand way to put and call things in multidimentional way.

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 7:17 am
by Tabaqui
Hi, Bowlman! The concept is the same in Lua too:

Code: Select all

// Load your images inside love.load
function love.load()
  // Declare your image table. This will be a table of tables, where each subtable will hold your images
  images = {}
  // Loop for each image
  for i = 1, 10 do
    // Entry "i" of your multidimensional table will be a table (array of images)
    images[i] = {}
    // Loop for each frame
    for j = 1, 18 do
      // Here i'm creating the image name dynamically based on the image and frame indexes using string.format (ex: image1_1.png)
      local imageName = string.format("image%d_%d.png", i, j)
      // Load your image and place it in the subtable with index "i" at index "j"
      images[i][j] = love.graphics.newImage(imageName)
    end
  end
end

// Use your images inside love.draw
function love.draw()
  //Draw image 5_5 at coordinates 0, 0
  love.graphics.draw(images[5][5], 0, 0)
end

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 7:29 am
by Bowlman
So you need to define all the different "slot" on that array? I thought you could do it once and be done. I think thats the thing I missed and I couldnt make it work. I think this helps. Thanks. Do you think this is the way to go? Or is there more streamlined approach you would suggest?

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 7:47 am
by zorg
I think that is a fine way of doing it, and yes, lua (the language löve gives you to use) expects you to define all inner tables you want to use, after all, you can't index nothing.

You could write a small helper function to define them for you, but having images[ i ] = {} in the outer loop is not that big of a deal either.

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 8:22 am
by togFox
Hypothetically, for education sake, to redraw those images in a 10x10 grid, is it safe to use integer indexes? I assume using ipairs is more robust if an index is deleted?

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 11:23 am
by zorg
togFox wrote: Fri Apr 09, 2021 8:22 am Hypothetically, for education sake, to redraw those images in a 10x10 grid, is it safe to use integer indexes? I assume using ipairs is more robust if an index is deleted?
safe how? the example already used integer indices... or do you mean just using a 1D array instead?

ipairs will also be worse in terms of, unlike a simple for loop, it can't handle gaps; it will stop if an entry would be missing, unlike a for loop (where you could/would need to write code to handle that case)

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 1:39 pm
by togFox
If images[3][5] (for example was deleted from the list/table/array then ipairs would cope with that. For i = 1,10 probably would not (would return nil when it got to the unexpectedly missing item). Yes?

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 6:06 pm
by zorg
Almost.

for i=1,10 would cope with it in terms of returning nil on the item.

ipairs would stop iterating on the first gap.

you decide which is worse, having one gap, or an arbitrary part of the map missing. :3

(that said, due to we're using nested tables, it's of course a bit more complicated)

Re: Multidimentional arrays/Tables

Posted: Fri Apr 09, 2021 9:04 pm
by tomxp411
togFox wrote: Fri Apr 09, 2021 1:39 pm If images[3][5] (for example was deleted from the list/table/array then ipairs would cope with that. For i = 1,10 probably would not (would return nil when it got to the unexpectedly missing item). Yes?
If you use table.remove to remove an element from the middle of the array, then there's no problem - the numbering will still be contiguous.

However, there will no longer be 10 items. So instead of

Code: Select all

for i=1,10
you should use

Code: Select all

for i=1,table.maxn(images[j])
I'm a big believer in readability, and part of the reason I'd use a for loop to read back the data is that I used a for loop to populate it in the first place, and the indices are numeric - which implies an array structure, even if that's not how it's really implemented internally in Lua.

If the data was stored with text or non-contiguous indices (such as hash values), then I'd use ipairs, as this makes it clear that the indices are associative values, rather than ordinals.

For the same reason, when I'm working in c# or VB, I'll use for(...) or for/next for linear arrays, even though foreach can handle both linear and associative arrays.

Re: Multidimentional arrays/Tables

Posted: Mon Apr 12, 2021 8:07 pm
by milon
You can also use the # prefix to get the size of a table (much simpler, IMO). Here's a 2D nested example of that:

Code: Select all

local images = {}
for i = 1, #images do
    images[i] = {}
    for j = 1, #images[i] do
        images[i][j] = love.graphics.newImage(imageName)
    end
end
Just keep in mind that each images[x] entry is itself a table - if you remove it or otherwise make it a non-table, then expressions such as "images[x][y]" will fail. If that's a possibility, you'll need to test for it.