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

Searching tables and getting display names

Started by siskulous, 01 December 2014 - 12:13 PM
siskulous #1
Posted 01 December 2014 - 01:13 PM
I've got two questions for a project I've been working on.

First, I've got a table of tables that I need to be able to search efficiently. I'm essentially using it as a crude database. Is there any way to do this other than looping through the whole table looking for one of the sub-tables where the variable I'm looking for matches the input? (I really hope that made sense, sorry if it doesn't.) Or, failing that, is there a real database-type program that runs in ComputerCraft?

Second, what's the best way for a turtle to get the display name of an item in it's inventory? I've tried turtle.getItemDetails, but that doesn't return the display name. So far the only way I've found that works reliably is using OpenPeripherals to check it once it's in a chest. If I have to I can use this method, but I'm trying to avoid needing anything other than CC itself.
theoriginalbit #2
Posted 01 December 2014 - 01:53 PM
For the first point. Well you could use the associative array nature of the tables by storing the sub-tables (and consequent data in those) by some form of ID, or name.
Take this database example

local databases = {}

function newDatabase( name )
  if databases[name] then --# check if there is already a value
    error( "a database with that name already exists", 2 ) --# error to the calling function stating that name is in use
  end
  databases[name] = {} --# make the database
end

function newTable( dbName, tblName )
  local db = databases[dbName] --# get the database (if there isn't one by that name this will be nil)
  if not db then --# check the database wasn't nil
    error( "no database by that name", 2 )
  end
  if db[tblName] then
    error( "there is already a table by that name" , 2 )
  end
  db[tblName] = {} --# create the table
end

function addEntry( dbName, tblName, value )
  local db = databases[dbName] --# get the database (if there isn't one by that name this will be nil)
  if not db then --# check the database wasn't nil
    error( "no database by that name", 2 )
  end
  local tbl = db[tblName]
  if not tbl then
    error( "there is no table by that name" , 2 )
  end
  local id = table.maxn( tbl ) + 1 --# get the index after the last one, so if there are entries in 0 thru 9 then this will be 10
  tbl[id] = value --# insert the value
  return id --# return the index
end

function query( db, tbl, id )
  local db = databases[dbName] --# get the database (if there isn't one by that name this will be nil)
  if not db then --# check the database wasn't nil
    error( "no database by that name", 2 )
  end
  local tbl = db[tblName]
  if not tbl then
    error( "there is no table by that name" , 2 )
  end
  return tbl[id] --# returns the entry under that ID, or nil if there isn't one.
end
however it really depends on how you want to tackle this problem

For the second point, you can't do this in ComputerCraft, you could use the Narcissistic Turtle from OpenP so it can search its own inventory instead of needing a chest.
siskulous #3
Posted 01 December 2014 - 03:08 PM
For the first point. Well you could use the associative array nature of the tables by storing the sub-tables (and consequent data in those) by some form of ID, or name.

That's essentially what I'm doing right now, but there are two different values I need to be able to search by to get one of the features on my todo list working. I may just need to approach the feature from a different direction.

For the second point, you can't do this in ComputerCraft, you could use the Narcissistic Turtle from OpenP so it can search its own inventory instead of needing a chest.

I guess that's what I'll do then. Having to have OpenP is workable if the alternative is using ids instead of display names, especially since it has a few other features not in CC that can help speed up my system. I was trying to stick with just CC to make distributing the project later on easier, but adding OpenP makes a few other things easier to.

I'll have to look at the Narcissistic Turtle. I didn't know about it before. Thanks for that.
theoriginalbit #4
Posted 02 December 2014 - 02:27 AM
That's essentially what I'm doing right now, but there are two different values I need to be able to search by to get one of the features on my todo list working. I may just need to approach the feature from a different direction.
the other way you could do it is you could have a table that acts as a lookup based on the 'different values' which in turn these tables store the reference for the main database entry. so take this extremely basic example


local databases = {
  someDb = {}
}
local lookup = {
  blocks = databases.someDb;
  items = databases.someDb;
}
with the above code lookup.blocks or lookup.items would both return the same database reference.