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

Table Help

Started by Cycomantis, 21 July 2014 - 01:37 AM
Cycomantis #1
Posted 21 July 2014 - 03:37 AM
I am working with OpenCCSensors for my first time and I'm having a problem access the data for my BuildCraft Tanks.

Here is an example of the table that I'm having problems with:
Spoiler

{
  Tanks = {
	{
	  RawName = "fluid.jet fuel",
	  Temperature = 295,
	  Name = "jet fuel",
	  Luminousity = 0,
	  Viscosity = 800,
	  Amount = 24000,
	  Capacity = 48000,
	  IsGaseous = false,
	},
  },
  DamageValue = 0,
  Position = {
	Y = 0,
	X = -1,
	Z = -1,
  },
  RawName = "buildcraft.tank",
  Name = "Tank",
}

How do I access the values stored in the "Tanks" array? I have never worked with a table thats formatted table.index = { { k = v } }

Here is the solution I've found for now. Can anyone improve on it? I'm not to fond of the nested loops.

local function getDetails()
	tDetails = {}
	for _,targetName in pairs(tTargets) do
		results = sens.getTargetDetails(targetName)
		tTanks = results.Tanks
		for _,tank in pairs(tTanks) do
			for k,dets in pairs(tank) do
				if tostring(k) == "Name" then tankName = tostring(dets)
				elseif tostring(k) == "Amount" then sAmount = tostring(dets)
				elseif tostring(k) == "Capacity" then sCapacity = tostring(dets)
				end
			end
			if tankName then
				if tankName == "jet fuel" then tankName = "jet_fuel" end
				tDetails[tankName] = { ["Amount"] = sAmount, ["Capacity"] = sCapacity }
			end
		end
	end
	return tDetails
end
Edited on 21 July 2014 - 03:00 AM
Bomb Bloke #2
Posted 21 July 2014 - 05:29 AM
By looking at the structure, we can determine the direct references like so:

Spoiler
results = {                            -- results
  Tanks = {                            -- results["Tanks"]
        {                              -- results["Tanks"][1]
          RawName = "fluid.jet fuel",  -- results["Tanks"][1]["RawName"]
          Temperature = 295,           -- results["Tanks"][1]["Temperature"]
          Name = "jet fuel",           -- results["Tanks"][1]["Name"]
          Luminousity = 0,             -- results["Tanks"][1]["Luminousity"]
          Viscosity = 800,             -- results["Tanks"][1]["Viscosity"]
          Amount = 24000,              -- results["Tanks"][1]["Amount"]
          Capacity = 48000,            -- results["Tanks"][1]["Capacity"]
          IsGaseous = false,           -- results["Tanks"][1]["IsGaseous"]
        },
  },
  DamageValue = 0,                     -- results["DamageValue"]
  Position = {                         -- results["Position"]
        Y = 0,                         -- results["Position"]["Y"]
        X = -1,                        -- results["Position"]["X"]
        Z = -1,                        -- results["Position"]["Z"]
  },
  RawName = "buildcraft.tank",         -- results["RawName"]
  Name = "Tank",                       -- results["Name"]
}

Now, with table indexes that are in the form of strings, there's no need to use the brackets to reference them - you can use the dot notation instead. Example:

Spoiler
results = {                            -- results
  Tanks = {                            -- results.Tanks
        {                              -- results.Tanks[1]
          RawName = "fluid.jet fuel",  -- results.Tanks[1].Rawname
          Temperature = 295,           -- results.Tanks[1].Temperature
          Name = "jet fuel",           -- results.Tanks[1].Name
          Luminousity = 0,             -- results.Tanks[1].Luminousity
          Viscosity = 800,             -- results.Tanks[1].Viscosity
          Amount = 24000,              -- results.Tanks[1].Amount
          Capacity = 48000,            -- results.Tanks[1].Capacity
          IsGaseous = false,           -- results.Tanks[1].IsGaseous
        },
  },
  DamageValue = 0,                     -- results.DamageValue
  Position = {                         -- results.Position
        Y = 0,                         -- results.Position.Y
        X = -1,                        -- results.Position.X
        Z = -1,                        -- results.Position.Z
  },
  RawName = "buildcraft.tank",         -- results.RawName
  Name = "Tank",                       -- results.Name
}

So, with all that in mind, you should be able to re-write your function like this:

Spoiler
local function getDetails()
	local results = sens.getTargetDetails(targetName)  -- Don't forget variable localisation!

	if results.Tanks[1] then  -- Make sure we got data for at least one tank back.
		if results.Tanks[1].Name == "jet fuel" then results.Tanks[1].Name = "jet_fuel" end
		return {["Name"] = results.Tanks[1].Name, ["Amount"] = results.Tanks[1].Amount, ["Capacity"] = results.Tanks[1].Capacity}
	else return false end
end

local myTank = getDetails()

if myTank then print("I found a tank called "..myTank.Name.."!") end
Cycomantis #3
Posted 21 July 2014 - 05:39 AM
By looking at the structure, we can determine the direct references like so:

Spoiler
results = {							-- results
  Tanks = {							-- results["Tanks"]
		{							  -- results["Tanks"][1]
		  RawName = "fluid.jet fuel",  -- results["Tanks"][1]["RawName"]
		  Temperature = 295,		   -- results["Tanks"][1]["Temperature"]
		  Name = "jet fuel",		   -- results["Tanks"][1]["Name"]
		  Luminousity = 0,			 -- results["Tanks"][1]["Luminousity"]
		  Viscosity = 800,			 -- results["Tanks"][1]["Viscosity"]
		  Amount = 24000,			  -- results["Tanks"][1]["Amount"]
		  Capacity = 48000,			-- results["Tanks"][1]["Capacity"]
		  IsGaseous = false,		   -- results["Tanks"][1]["IsGaseous"]
		},
  },
  DamageValue = 0,					 -- results["DamageValue"]
  Position = {						 -- results["Position"]
		Y = 0,						 -- results["Position"]["Y"]
		X = -1,						-- results["Position"]["X"]
		Z = -1,						-- results["Position"]["Z"]
  },
  RawName = "buildcraft.tank",		 -- results["RawName"]
  Name = "Tank",					   -- results["Name"]
}

Now, with table indexes that are in the form of strings, there's no need to use the brackets to reference them - you can use the dot notation instead. Example:

Spoiler
results = {							-- results
  Tanks = {							-- results.Tanks
		{							  -- results.Tanks[1]
		  RawName = "fluid.jet fuel",  -- results.Tanks[1].Rawname
		  Temperature = 295,		   -- results.Tanks[1].Temperature
		  Name = "jet fuel",		   -- results.Tanks[1].Name
		  Luminousity = 0,			 -- results.Tanks[1].Luminousity
		  Viscosity = 800,			 -- results.Tanks[1].Viscosity
		  Amount = 24000,			  -- results.Tanks[1].Amount
		  Capacity = 48000,			-- results.Tanks[1].Capacity
		  IsGaseous = false,		   -- results.Tanks[1].IsGaseous
		},
  },
  DamageValue = 0,					 -- results.DamageValue
  Position = {						 -- results.Position
		Y = 0,						 -- results.Position.Y
		X = -1,						-- results.Position.X
		Z = -1,						-- results.Position.Z
  },
  RawName = "buildcraft.tank",		 -- results.RawName
  Name = "Tank",					   -- results.Name
}

So, with all that in mind, you should be able to re-write your function like this:

Spoiler
local function getDetails()
	local results = sens.getTargetDetails(targetName)  -- Don't forget variable localisation!

	if results.Tanks[1] then  -- Make sure we got data for at least one tank back.
		if results.Tanks[1].Name == "jet fuel" then results.Tanks[1].Name = "jet_fuel" end
		return {["Name"] = results.Tanks[1].Name, ["Amount"] = results.Tanks[1].Amount, ["Capacity"] = results.Tanks[1].Capacity}
	else return false end
end

local myTank = getDetails()

if myTank then print("I found a tank called "..myTank.Name.."!") end

Exactly what I was looking for. Thank you very much!!!!

I ended up with the following to record the used capacity for each of the different tanks I have setup.
Spoiler

local function getDetails()
    tDetails = {}
    for _,targetName in pairs(tTargets) do
        tankName = sens.getTargetDetails(targetName).Tanks[1].Name
        if tankName then
            if tankName == "jet fuel" then tankName = "jet_fuel" end
            tDetails[tankName] = { ["Amount"] = sens.getTargetDetails(targetName).Tanks[1].Amount, ["Capacity"] = sens.getTargetDetails(targetName).Tanks[1].Capacity }
        end
    end
    return tDetails
end
Edited on 21 July 2014 - 03:50 AM