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

Sort a table alphabetically

Started by tommynov, 01 April 2014 - 01:48 AM
tommynov #1
Posted 01 April 2014 - 03:48 AM
First of all, this code is meant to scan essentia in Warded Jars in the mod called Thaumcraft 4. Some knowledge might help understand the code itself a little bit.

I have downloaded a copy of "button" and "aspects" from DireWolf20. I don't know too much LUA, however, but I do know enough to know what the program itself does.
Link for aspects - pastebin(dot)com/2Vx1jthe
Link for button - pastebin(dot)com/z0FBM6wd

Button creates the buttons on a touch screen monitor using hard-coded x and y coordinates to determine where each variable in the table essentia (located in aspects) goes. It is also used later, in fillTable2 (in aspects) for example, to define where certain buttons go and what kind of parameters can be accepted depending on the button pushed.

scanEssentia uses PeripheralProxy's and wired modems to scan the amount of essentia in a jar as well as what type of essentia. It then puts the name of the essentia by using the variable asp. There are 50+ types of essentia, so looking at all of these on a screen without being alphabetically ordered is quite a hasel. The way the code is defined is that it runs off an infinite loop, and each time the code is terminated, and restarted the list itself might be in a different order. For example, three aspects are called aer, terra, and momentum. The first time the code is ran it could print terra, aer, and then momentum on the monitor. Then, once terminated and reran, the monitor may display it by saying aer, terra and then momentum. I simply just wish to alphabeticalize these varibles, but i cannot seem to get table.sort to work. I simply am not sure whether or not asp is what I want to use, or essentia.

The code from the pastebin links are largely unedited by myself other than a function to go back to fillTable when I am in fillTable2.

Thanks!
theoriginalbit #2
Posted 01 April 2014 - 06:46 AM
Okay so the reason that they're being accessed in any order is due to the way the pairs function works; you're using it on line 29. Basically pairs will access the elements in order when they're numerical indexes, but when dealing with keys (strings), like you're doing here, they can be in any order. As such we need to write a function to iterate through the table in an ordered manner.

So how do we do this? well first we define a function at the top of your code (just below the variables), lets call it orderedPairs

local function orderedPairs( tbl )
  --# code
end

now what we need to do is get a list of all the keys that exist in the table currently — these keys are your Aspect names — so that we can use them as a reference for alphabetical order. So the function now becomes this

local function orderedPairs( tbl )
  local keys = {}
  for name in pairs( tbl ) do
    table.insert(keys, name)
  end
end

now notice here we use pairs, this is because at this point in time we don't care about order, we're about to put them into order now. also notice how we've inserted the names into the keys table not as a key, but with a numerical index, this is so table.sort can sort them correctly. So now lets make them sorted in alphabetical order

local function orderedPairs( tbl )
  local keys = {}
  for name in pairs( tbl ) do
    table.insert(keys, name)
  end
  table.sort(keys)
end
easy right? but we're not done yet, because we only have a table of the keys, we need the values for you as well, and don't forget this is being called in the other loop, so we need to return the name and value for that. So how do we do this? easy, we start by defining a 'current index' variable, we return a function for the original for loop which increments this 'current index' variable and returns the appropriate key and value


local function orderedPairs( tbl )
  local keys = {}
  for name in pairs( tbl ) do
    table.insert(keys, name)
  end
  local index = 0
  return function()
    index = index + 1
    local key = keys[index]
    return key, tbl[key]
  end
end
notice how we get the key from the keys table — this ensures that its alphabetical order — and then we use that key to look up the original value. What now? well that's it, we're done, we've now implemented a function that will return our table in an alphabetical order. But how do you use it? easy change line 29 to say

for i,j in orderedPairs(essentia) do

Link for aspects - pastebin(dot)com/2Vx1jthe
Link for button - pastebin(dot)com/z0FBM6wd
You don't need to do the '(dot)' on these forums, pastebin as well as many other links are allowed…
CometWolf #3
Posted 01 April 2014 - 07:38 AM
Edit: ignore me, bit's got it handled. I had this tab open on my phone for a while :P/>

The table you need to sort is essentia. The amount of each aspect is indexed by it's name in the essentia table. However the order of the elements in a table is irrelevant when you iterate through it with a pairs loop, so sorting it won't help. You'll have to restructure the table to a numerically indexed one containing a table with the name and amount of each aspect, sort it, then iterate through it with a regular for loop.
Edited on 01 April 2014 - 05:40 AM
tommynov #4
Posted 01 April 2014 - 11:15 PM
Alright, thanks for that! Now, with that new function, when I want to fill the requested amount of essence, I want to be able to call a function where a turtle (connected via wireless router) that will take a mana bean (which is in a certain slot in a chest that will never change due to the fact CC can't probably read what type of essentia a mana bean has) from a certain slot and put it into the alchemical furnace.

The code (if necessary) for catalogue is here: http://pastebin.com/7BjsWxtR
Basically all that this program does is record the type of essentia that a mana bean in a certain chest slot has. The chest slot will always contain that type of mana bean.

So, my question is, how do I properly hook up a turtle to the main computer (the one running aspects) using wireless routers so that when I click the button "Execute fill request", the turtle will put the exact number of mana beans (the number you get from the addEss function) into the alchemical furnace?