This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Joe3000's profile picture

How to create a table inside a table using table.insert()

Started by Joe3000, 25 May 2013 - 01:18 AM
Joe3000 #1
Posted 25 May 2013 - 03:18 AM
I'm still kinda new to CC so I was wondering if it's possible. If it is possible, how would you go about doing it?
Lyqyd #2
Posted 25 May 2013 - 03:31 AM
Not entirely sure where table.insert comes in–it can't create tables. Tables in tables are easy, though.


myTable = {}
myTable.innerTable = {}
myTable.innerTable.key = 42
theoriginalbit #3
Posted 25 May 2013 - 03:42 AM
you can also do what Lyqyd stated above without a name for the inner table, and instead just a number like so

myTable = {}
myTable[1] = {}
myTable[1].key = 42

you can use table.insert to do something like this

myTable = {}
table.insert(myTable, { "some", "data", "goes", "here", 1, 2, 3, 4, 5, ["or it could be empty"] = true })
and that would insert a table at index 1, or the index thats the last index, whatever that may be, example

myTable = {}
table.insert(myTable, {}) --# index 1
table.insert(myTable, {}) --# index 2
myTable[3] = "something"
table.insert(myTable, {}) --# index 4
Joe3000 #4
Posted 25 May 2013 - 11:42 AM
I understand what you guys are saying, but what I'm trying to do is get my turtle to store a lot of information (maybe there is another way to do this but I just figure that tables are the way(if there is an easier way please tell me because i'm still a noob with this stuff)). So for instance, I want to have a blank table, and then my turtle is going to do something, and inside that table he would need to insert another table to store that data, then he would move, do some more stuff, and in the second index of the first table he would create another table, and store info. in there and so on…. This is a code that I learned has not worked but its kinda what i'm getting at

local t = { }
while true do
turtle.dostuff
turtle.dostuff
if turtle.dostuff then
tabel.inster(t, {{information}})
end
end
theoriginalbit #5
Posted 25 May 2013 - 12:06 PM
well the code you have there would create this structure

local t = {
  { { information } },
  { { information } },
  { { information } },
}
so assuming you wanted to grab the third piece of information from the second table you would need to do this

t[2][1][3]
that is because when you're inserting the table into t, you're actually inserting a table in a table.

an untested example. the turtle should move along a path, and then move back along it, taking the exact amount of time in between movements

local moveHistory = {}
local lastMove = os.clock()

local function moveForward()
  if turtle.forward() then
    local timeSinceLastMove = os.clock() - lastMove
    lastMove = os.clock()
    table.insert(moveHistory, { delayTime = timeSinceLastMove, reverseMove = turtle.back })
  end
end

local function turnRight()
  if turtle.turnRight() then
    local timeSinceLastMove = os.clock() - lastMove
    lastMove = os.clock()
    table.insert(moveHistory, { delayTime = timeSinceLastMove, reverseMove = turtle.turnLeft })
  end
end

-- assume I have made similar functions for back, up, down, and turn left.

local function movePath()
  moveForward()
  sleep(0.5)
  moveForward()
  sleep(0.8)
  turnLeft()
  sleep(1)
  moveForward()
  sleep(4)
  turnRight()
  moveBack()
  moveForward()
  moveForward()
  sleep(0.2)
  moveForward()
end

local function backtrack()
  for i = 1, #moveHistory do
    local node = moveHistory[i]
    sleep(node.delayTime)
    node.reverseMove()
  end
end

movePath()
backtrack()
Joe3000 #6
Posted 25 May 2013 - 01:20 PM
Thanks!! I got it!! you where write, all i have to do is put {} in second part of it table.insert()!!! Thanks a bunch!
diegodan1893 #7
Posted 25 May 2013 - 01:49 PM
Yes, tables can store any kind of variable, so you can do table.insert() with another table and you will insert it to the first table, or you can create the table TheOriginalBIT suggested. But that also works for numbers, strings and even functions. When used correctly tables are the best tool in Lua.
theoriginalbit #8
Posted 25 May 2013 - 01:53 PM
When used correctly tables are the best tool in Lua.
And when not used correctly can be the biggest annoyance, and hindrance to programmer and program.

Note for diegodan1893
Spoiler
TheOriginalBIT suggested
Thank you for getting the capitalisation correct :)/>
Joe3000 #9
Posted 25 May 2013 - 10:19 PM
Alright, so earlier I posted a question asking how to use table.insert() to make a table inside a table, and now I figured that out, but now I need to figure out how to add info to that second table. I don't want to have to wait till I have all the info and save them to variables or something then make the second table and add them altogether, that sounds tedious, so how would I add info to this new table?
Lyqyd #10
Posted 25 May 2013 - 10:34 PM
Threads merged. For closely related questions, or questions about the same piece of code, please ask the subsequent question in the same topic.

You can add info to the table the same way you add information to any other table.

outerTable.innerTable = newValue
Joe3000 #11
Posted 26 May 2013 - 01:33 AM
Yes thank you that worked…. and now my last and final question (hopefully) if you are making lots of tables inside one table and you make a counter to change the name of the "deeper" (so to speak) tables to keep them from getting mixed up, how would you write that with that last command? this might sound really confusing, but this is kinda what i'm trying to go at…

counter = 1
local table = { }
while blabla do
turtle.dostuff
if turtle.dostuff then
table.(counter) = {"1"}
counter = counter + 1
end
end


this doesn't work because it keeps wanting a name for the second table, so how would you go about doing that?
Bomb Bloke #12
Posted 26 May 2013 - 01:44 AM
It's probably easier to go like this:

counter = 1
local table = { }
while blabla do
  if turtle.forward() then
	table[counter] = 1
	counter = counter + 1
  end
end

(Remember, when checking something like "if turtle.forward() then", that action will be performed during your check, if possible!)

Further examples for nesting tables;
local temptable = {}
temptable[1] = {3,4} -- temptable[1][1] is 3, temptable[1][2] is 4
temptable[2] = {5,6} -- temptable[2][1] is 5, temptable[2][2] is 5
temptable[2][2] = {7,8} -- temptable[2][2] is no longer 5, but now another table; temptable[2][2][1] is 7, temptable[2][2][2] is 8

You could also define the whole table in a single line, if you happened to know the desired structure ahead of time:

temptable = {{3,4},{5,{7,8}}}

However, I'd be thinking hard about how much data you're wanting to nest in your tables. I suspect you're planning on cramming more and more data in for every action your turtle takes (until you run out of memory and crash your program), when you're only really needing to store it for a certain amount of time - at which point you should be backtracking and re-using your old table indexes.
Joe3000 #13
Posted 26 May 2013 - 01:58 AM

It's probably easier to go like this:

counter = 1
local table = { }
while blabla do
  if turtle.dostuff then
	table[counter] = 1
	counter = counter + 1
  end
end
(Remember, when checking "if turtle.action() then", that action will be performed during your check, if possible!)


What you said makes sense, but its not what I'm going for. You see, i'm trying to make a "mapping" system, nothing really advanced, im just trying to get practice with tables, but i want the turtle.to move forward a block, turn and check both sides with turtle.detect() and if true then set table[1] = {true, false, true}(or whatever they need be). So when the turtle.turns to the left, and detect returns true, it needs to save in table[1][1], and when it turns to the right it needs to save in table[1][2] and finally when it moves forward it will start saving in table[2][1] and so on… maybe there is an easier way to do this… but this is what i have gotten so far…

local learn = { }
local count = 1
function detect()
if turtle.detect() then
learn.count = {"1"}
else
learn.[count] = {"0"}
end
end
function forward()
turtle.forward()
detect()
turtle.turnLeft()
detect()
turtle.turnRight()
turtle.turnRight()
turtle.detect()
turtle.turnLeft()
count = count + 1
end
while not turtle.detect() do
forward()
end


–Edit–
I don't plan to really make this going that far, im just trying to make it go forward 10 blocks max. I just want to have a little bit more practice with tables and how to make them interact with the turtle's environment
Bomb Bloke #14
Posted 26 May 2013 - 02:17 AM
When you store {"1"}, you're creating a new table with one single index which has the text (as opposed to the number) "1" stored in it as a string. There's no point in a single-index table, there's no point in the string; you may as well just store the number 1.

You can also store booleans (true/false) values in tables. Instead of going "if condition then variable = 1 end", you can simply type "variable = condition", and then later you can check what that result was by going "if variable then task end".

I would scrap your detect function altogether, as it's making things more complex then they need to be.

local learn = { }
local count = 1
function forward()
  turtle.forward()
  learn[count][1] = turtle.detect()
  turtle.turnLeft()
  learn[count][2] = turtle.detect()
  turtle.turnRight()
  turtle.turnRight()
  learn[count][3] = turtle.detect()
  turtle.turnLeft()
  count = count + 1
end
while not turtle.detect() do
  forward()
end

When this is complete:

learn[1][1] will be false if there was space in front of the turtle at the start.
learn[1][2] will be false if there was space to the left of the turtle at the start.
learn[1][3] will be false if there was space to the right of the turtle at the start.

learn[2][1] will be false if there was space in front of the turtle after moving ahead once.
learn[2][2] will be false if there was space to the left of the turtle after moving ahead once.
learn[2][3] will be false if there was space to the right of the turtle after moving ahead once.

learn[3][1] will be false if there was space in front of the turtle after moving ahead twice.
learn[3][2] will be false if there was space to the left of the turtle after moving ahead twice.
learn[3][3] will be false if there was space to the right of the turtle after moving ahead twice.

And so on. One table containing three values for every movement made. So, say later you wanted to know how far the turtle had to move before the space to its left was open, you could simply go:

for i,table.getn(learn) do  -- Start a loop that'll count from 1 to the number of tables stored in the "learn" table
  if not learn[i][2] then  -- Check the second index of the table stored in learn[i], and if was false, then...
	print("There was a space to my left at position number "..i..".")
	break
  end
end
Joe3000 #15
Posted 26 May 2013 - 02:47 AM
I tried that code and I got an error saying that an index was expected on line 4…. Idk whats wrong….
Bomb Bloke #16
Posted 26 May 2013 - 02:56 AM
Ah, sorry, put a "learn[count] = {}" under the "function forward()" line. It already knows "learn" is a table, this creates the table in that table - the one you're going to put your actual data into.
Joe3000 #17
Posted 26 May 2013 - 03:09 AM
Yes! That worked! Thank you so much! Now I'm going to save this code and recall on it if I ever have any more problems with tables and "Table Inception"
Joe3000 #18
Posted 27 May 2013 - 01:53 AM
Alright, I lied, I have a new question about tables. Is there a way to tell if a value is in a table or not?

–Edit–
Also, is there any other way for turtles to compare things besides having them in their inventory? For example, is it possible to set the ID of dirt (for a turtle) to 1 and the ID of wood to two? So when a turtle comes across a wood block it breaks it, recognizes that it has the ID 2 and then does whatever with it?

–Edit–
Perhaps I should start a new topic since I have begun to drift off the subject of this topic…