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

Problem with nested for loop

Started by zeronoashaen, 26 January 2014 - 11:18 PM
zeronoashaen #1
Posted 27 January 2014 - 12:18 AM
So I am having a problem with a nested for loop in my command. The purpose of this code is to compare the players inventory with a list of items on a SQL server. All the functions by itself works fine, but if I try to compare them like this it will only grab it if it is in the first position in my inventory.


if sellItems[1] ~= nil then
   for i=1, #sellItems do
	  sell = ocgui.newMenuItem()
	  item = tostring(sellItems[i].RawName)
	  for j=1, #sItemsTable do
		 check = tostring(sItemsTable[j].rawName)
		 if (item == check) then
			dNameS = tostring(sItemsTable[j].dspName)
			if(string.find(dNameS, "%s") ~= nil and string.len(dNameS) > 8) then
			   dNameS= string.sub(dNameS, 1, 2).."."..string.sub(dNameS, string.find(dNameS, "%s"), -1)
			   dNameS= string.sub(dNameS, 1, 8)
			end
			sell:newName(dNameS)
			sell:newType("sellItem")
			sell:newColour(colors.white)
			sell:setData(sItemsTable[j])
			table.insert(sMenuItemList, sell)
			table.insert(sItemsList, sellItems[i])
		 end
	  end
   end
else
   invPlayer = 0
end
Edited on 26 January 2014 - 11:37 PM
surferpup #2
Posted 27 January 2014 - 12:33 AM
First, change this line


if sellItems[1] ~= nil then

To


if sellItems[1] then


Likewise, change


if(string.find(dNameS, "%s") ~= nil and string.len(dNameS) > 8) then

To


if(string.find(dNameS, "%s") and string.len(dNameS) > 8) then

That is much better form. The variables will be true if they are not nil, so just test if they are true.

Also, you do realize that this code will ONLY execute if there is a value in sellItems[1]?
Edited on 26 January 2014 - 11:33 PM
zeronoashaen #3
Posted 27 January 2014 - 12:52 AM
If there is not a value in sellItems[1] then there is nothing in the players inventory and thus doesn't need to run.
surferpup #4
Posted 27 January 2014 - 01:03 AM
Fair enough. Have you printed #sellItems before the for i loop? Does it indicate the number you expect? The reason I suggested changing from the ~=nil form is that I have run into trouble with it in the past. It may not be critical, but I change it when I see it.
Edited on 27 January 2014 - 12:04 AM
CometWolf #5
Posted 27 January 2014 - 05:42 AM
How are you getting the inventory data? Note that # only returns the amount of keyes from 1 to the first nil value. As such a pairs for loop might work better.
Edited on 27 January 2014 - 04:43 AM
zeronoashaen #6
Posted 27 January 2014 - 06:57 PM
I am using a openccsensors script to pull the players inventory. I want to pull the players inventory, compare it with my database, and if they are in my database put them into my sMenuItemList array. I also need to check to see if there are any duplicates so instead of adding another menu item I can increase the item amount.
CometWolf #7
Posted 28 January 2014 - 12:25 AM
I figured as much. Since you're using openP, you'll have to use the pairs iterator in your loop. Using # with a numerically indexed table with holes in it will return the first key prior to the first hole(nil value). OpenP gives you a numerically indexed table, but every empty slot will be nil.

local tTable = {
  [1] = "derp"
  [2] = nil -- hole
  [3] = "passed a hole!"
}
for i = 1,#tTable do
  print(tTable[i]) -- only prints derp
end

for k,v in pairs(tTable) do --k will be the index key, and v will be the value it holds.
  print(k.."="..v) -- prints both 1 and 3
end