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

ipairs() doesn't work?

Started by digpoe, 24 March 2013 - 12:02 AM
digpoe #1
Posted 24 March 2013 - 01:02 AM
I'm making a computer that shows the index, value pairs in a list, but using pairs() it isn't in order
(Ex:
Spoiler

list = {
["Hey"] = [[
1) bleh
2) hi
]],
["Bye"] = [[
1) hmm
2) heh
]]}
for i, v in pairs(list) do print(i) print(v) end
could turn out:

Hey
1) bleh
2) hi
(2nd item)

or

Bye
1) hmm
2) heh
(1st item)
)

I read on the ComputerCraft wiki that:

"Note that ipairs is identical to pairs, except it tries to do it in order."

So I assumed that if I used ipairs() in my for loop instead of pairs(), it would work in order. But apparently no, as when I restart the computer after saving the changes, the program doesn't even seem to run.

Here's my code, for those who are interested.

Spoiler

local items =
{
["A place to start"] = [[
1) Iron Chest
2) Quarry
3) Computer (CC)
4) Apiarist's Machine
5) Router
6) Solar Panel
7) Macerator
8) Electric Furnace
9) Compressor]],
["Getting advanced"] = [[
1) Induction Furnace
2) Mass Fabricator
3) Reactor Chamber
4) HV-Transformer
5) MFSU
6) Medium Voltage Solar Array
7) Teleporter
8) Tesla Coil
9) MFFS Projector]],
["Bad day for the creepers"] = [[
1) TNT
2) Nuke
3) Industrial TNT
4) Fire Charge
5) Dynamite
6) Fire Basin
7) Destruction Catalyst
8) Sulfuric Acid
9) Condensed Splash Serum]],
["Things that glow lots"] = [[
1) Glowstone
2) Touchstone of Midas
3) REther Pearl
4) Corrupted Essence
5) Potions of Swiftness (Speed II 1:30)
6) Nano Saber
7) Light Turtle (No other attachments)
8) Gravity Gun (Not Supercharged)
9) Redstone Lamp]]
}
local m = peripheral.wrap("top")
term.redirect(m)
m.setTextScale(2.5)
for i, v in ipairs(items) do --The ipairs() here used to be pairs(), and is the line that seems to be erroring without output
local event = os.pullEvent("monitor_touch")
term.clear()
term.setCursorPos(1, 1)
textutils.slowWrite(i)
term.setCursorPos(1, 2)
textutils.slowWrite(v)
end
theoriginalbit #2
Posted 24 March 2013 - 01:10 AM
ok so a few things here.

pairs iterates the key/value pairs in a table.

t = {
this = "some thing",
5,
6,
that = 'something else'
}
for k,v in pairs( t ) do
  print( k .. ':' .. v )
end
the above would print
1:5
2:6
this:some thing
that:something else
but anything that are keys (not a number) will not be in any order…

ipairs will not do anything with a key/value pair … so this


t = {
this = "some thing",
5,
6,
that = 'something else'
}
for k,v in pairs( t ) do
  print( k .. ':' .. v )
end
would output this
1:5
2:6

however do not use ipairs, there was a massive discussion about it a while ago and its better use an incremental loop over a generic loop. to the point that the new lua has removed ipairs. so you would do this


t = {
this = "some thing",
5,
6,
that = 'something else'
}
for i = 1, #t do
  print( t[i] )
end
would output the exact same thing as the ipairs one.


However for the actual problem you are having, is that you actually only have ONE value in the table, and that is the massive string. if you want to have them print out individually you need to store them as separate items in the table, or use textutils.pagedPrint
Whops nvm. just remove the keys. as stated above ipairs only accesses keys that are numbers (indexes), not strings.
Edited on 24 March 2013 - 12:12 AM
remiX #3
Posted 24 March 2013 - 01:10 AM
Pairs is in order, ipairs isn't, that's what I've been told.

Try this

List = {
["Hey"] = [[1) test
2) Gvkgre]],
["Bye"] = [[1) tjcnfr
2) Test]]
}

for i, v in pairs( List ) do
    print( i .. '\n' .. v )
end
digpoe #4
Posted 24 March 2013 - 01:11 AM
ok so a few things here.

pairs iterates the key/value pairs in a table.

t = {
this = "some thing",
5,
6,
that = 'something else'
}
for k,v in pairs( t ) do
  print( k .. ':' .. v )
end
the above would print
1:5
2:6
this:some thing
that:something else
but anything that are keys (not a number) will not be in any order…

ipairs will not do anything with a key/value pair … so this


t = {
this = "some thing",
5,
6,
that = 'something else'
}
for k,v in pairs( t ) do
  print( k .. ':' .. v )
end
would output this
1:5
2:6

however do not use ipairs, there was a massive discussion about it a while ago and its better use an incremental loop over a generic loop. to the point that the new lua has removed ipairs. so you would do this


t = {
this = "some thing",
5,
6,
that = 'something else'
}
for i = 1, #t do
  print( t[i] )
end
would output the exact same thing as the ipairs one.


However for the actual problem you are having, is that you actually only have ONE value in the table, and that is the massive string.

But doesn't that kind of for loop only iterate over tables with number indexes?
billysback #5
Posted 24 March 2013 - 01:12 AM
ipairs is pairs but in a numerical order, 1 to length ignoring all nil values (I believe) and values which cannot be placed in a numerical order.
pairs cannot - for obvious reasons - iterate in a numerical order as some of the values may not be numerical, they may not even be alphabetical, so it does it in a seemingly random order (not sure what the order actually is)

ipairs is, however, devoid of use. use for i instead.
digpoe #6
Posted 24 March 2013 - 01:15 AM
But if I have a table like this:


local items =
{
["Item1"] = "Hey",
["Item2"] = "Bye"
}

would 'for i = 1, #items' iterate through all of the items even though they're indexed a different way?
theoriginalbit #7
Posted 24 March 2013 - 01:15 AM
But doesn't that kind of for loop only iterate over tables with number indexes?
edited my post…. but ipairs only iterates over tables with indexes, your table does not have indexes


pairs cannot - for obvious reasons - iterate in a numerical order as some of the values may not be numerical, they may not even be alphabetical…
pairs does actually iterate over indexes in order and puts the index into the key, its just the key/value pairs that aren't in any order… it even iterates indexes first, then iterates keys.


would 'for i = 1, #items' iterate through all of the items even though they're indexed a different way?
No it wouldn't…. so just remove the keys, you don't need them, you aren't using them anywhere
digpoe #8
Posted 24 March 2013 - 01:16 AM
But doesn't that kind of for loop only iterate over tables with number indexes?
edited my post…. but ipairs only iterates over tables with indexes, your table does not have indexes


pairs cannot - for obvious reasons - iterate in a numerical order as some of the values may not be numerical, they may not even be alphabetical…
pairs does actually iterate over indexes in order and puts the index into the key, its just the key/value pairs that aren't in any order… it even iterates indexes first, then iterates keys.
My table does have indexes.


local items =
{
["A place to start"] = [[
1) Iron chest
...
]]
}

Are you telling me that ["A place to start"] isn't an index?
theoriginalbit #9
Posted 24 March 2013 - 01:17 AM
["A place to start"] is a key, not an index.

this uses indexes (1—4)

t = {
1,
5,
6,
7
}

so does this (it has 4 values at indexes 1, 2, 4 and 7)

t = {
1 = 1,
2 = 5,
4 = 6,
7 = 3
}
billysback #10
Posted 24 March 2013 - 01:18 AM
pairs cannot - for obvious reasons - iterate in a numerical order as some of the values may not be numerical, they may not even be alphabetical…
pairs does actually iterate over indexes in order and puts the index into the key, its just the key/value pairs that aren't in any order… it even iterates indexes first, then iterates keys.
not really sure what you mean by this, pairs does not iterate through a table in an obvious order - as it can't - I understand that it works with keys and values just as ipairs does?
digpoe #11
Posted 24 March 2013 - 01:21 AM
["A place to start"] is a key, not an index.

this uses indexes (1—4)

t = {
1,
5,
6,
7
}

so does this (it has 4 values at indexes 1, 2, 4 and 7)

t = {
1 = 1,
2 = 5,
4 = 6,
7 = 3
}

I believe we're getting mixed up on terminology here.

Your 'key' is equal to my 'index'.

The bulk of my table is:

["A place to start"] = [[
1) Iron chest

]]

["A place to start"] is the 'index' (or the way you would reference it if you used table[]) and the text in the [[]] is my 'value' for that 'index'.
theoriginalbit #12
Posted 24 March 2013 - 01:24 AM
not really sure what you mean by this, pairs does not iterate through a table in an obvious order - as it can't - I understand that it works with keys and values just as ipairs does?
here is an image, code and output … hopefully what I say will now make sense … http://puu.sh/2msbi


I believe we're getting mixed up on terminology here.

Your 'key' is equal to my 'index'.

The bulk of my table is:

["A place to start"] = [[
1) Iron chest

]]

["A place to start"] is the 'index' (or the way you would reference it if you used table[]) and the text in the [[]] is my 'value' for that 'index'.
No my key is not equivalent to your index…

this is a table using key/value pairs

t = {
 ["some key"] = "some value"
}

this is a table using indexes

t = {
  "some value"
}

here is another that uses indexes (notice its a number not a string

t = {
 5 = 'some value'
}
digpoe #13
Posted 24 March 2013 - 01:26 AM
not really sure what you mean by this, pairs does not iterate through a table in an obvious order - as it can't - I understand that it works with keys and values just as ipairs does?
here is an image, code and output … hopefully what I say will now make sense … http://puu.sh/2msbi


I believe we're getting mixed up on terminology here.

Your 'key' is equal to my 'index'.

The bulk of my table is:

["A place to start"] = [[
1) Iron chest

]]

["A place to start"] is the 'index' (or the way you would reference it if you used table[]) and the text in the [[]] is my 'value' for that 'index'.
No my key is not equivalent to your index…

this is a table using key/value pairs

t = {
["some key"] = "some value"
}

this is a table using indexes

t = {
  "some value"
}

here is another that uses indexes (notice its a number not a string

t = {
5 = 'some value'
}
Yes, we are getting mixed up. I have gotten into a habit of calling the way you 'index' or use a 'key' an 'index'. You're getting confused because of this.
billysback #14
Posted 24 March 2013 - 01:26 AM
oh, you meant that it iterates numerically then does a random iteration of the remaining values.
Didn't know that :P/> I generally use pairs as if the order will be random, usually safest.
theoriginalbit #15
Posted 24 March 2013 - 01:31 AM
Yes, we are getting mixed up. I have gotten into a habit of calling the way you 'index' or use a 'key' an 'index'. You're getting confused because of this.
In that case it is not me that is getting it wrong it is you. Professionally I know it as an indexed value and a key/value pair. in any case remove your "index" and it should be good…


oh, you meant that it iterates numerically then does a random iteration of the remaining values.
Didn't know that :P/> I generally use pairs as if the order will be random, usually safest.
Well it is still random for strings… it just does numerical indexes in the correct order first, then the rest are any order it decides (which is the same order everytime, just necessarily not the same as input)…
digpoe #16
Posted 24 March 2013 - 01:32 AM
Yes, we are getting mixed up. I have gotten into a habit of calling the way you 'index' or use a 'key' an 'index'. You're getting confused because of this.
In that case it is not me that is getting it wrong it is you. Professionally I know it as an indexed value and a key/value pair. in any case remove you "index" and it should be good…


oh, you meant that it iterates numerically then does a random iteration of the remaining values.
Didn't know that :P/> I generally use pairs as if the order will be random, usually safest.
Well it is still random for strings… it just does numerical indexes in the correct order first, then the rest are any order it decides (which is the same order everytime, just necessarily not the same as input)…

Yeah, I'll try and just merge them into one and then I can use pairs()
theoriginalbit #17
Posted 24 March 2013 - 01:34 AM
Yeah, I'll try and just merge them into one and then I can use pairs()
you're over complicating things massively, but sure, that should work…
digpoe #18
Posted 24 March 2013 - 01:35 AM
Yes, that seemed to work.

Here's the code that I got to work:

Spoiler

local items =
{
[[
A place to start
1) Iron Chest
2) Quarry
3) Computer (CC)
4) Apiarist's Machine
5) Router
6) Solar Panel
7) Macerator
8) Electric Furnace
9) Compressor]],
[[
Getting advanced
1) Induction Furnace
2) Mass Fabricator
3) Reactor Chamber
4) HV-Transformer
5) MFSU
6) Medium Voltage Solar Array
7) Teleporter
8) Tesla Coil
9) MFFS Projector]],
[[
Bad day for the creepers
1) TNT
2) Nuke
3) Industrial TNT
4) Fire Charge
5) Dynamite
6) Fire Basin
7) Destruction Catalyst
8) Sulfuric Acid
9) Condensed Splash Serum]],
[[
Things that glow lots
1) Glowstone
2) Touchstone of Midas
3) REther Pearl
4) Corrupted Essence
5) Potions of Swiftness (Speed II 1:30)
6) Nano Saber
7) Light Turtle (No other attachments)
8) Gravity Gun (Not Supercharged)
9) Redstone Lamp]]
}
local m = peripheral.wrap("top")
term.redirect(m)
m.setTextScale(2.5)
for _, v in pairs(items) do
local event = os.pullEvent("monitor_touch")
term.clear()
term.setCursorPos(1, 1)
textutils.slowWrite(v)
sleep(2)
end
theoriginalbit #19
Posted 24 March 2013 - 01:37 AM
Yes, that seemed to work.

Here's the code that I got to work:

-code snip-
haha so you changed them to indexes. when you said into one, i thought you meant one string…
digpoe #20
Posted 24 March 2013 - 01:39 AM
Yes, that seemed to work.

Here's the code that I got to work:

-code snip-
haha so you changed them to indexes. when you said into one, i thought you meant one string…
That would be too overly-complicated, to use string matching to find the last item and some other junk.
theoriginalbit #21
Posted 24 March 2013 - 01:53 AM
That would be too overly-complicated, to use string matching to find the last item and some other junk.
I can think of some nice and easy solutions, but yes for the most part, overly-complicated.