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

Storing position and value in a table

Started by LubsonGG, 27 August 2015 - 04:55 PM
LubsonGG #1
Posted 27 August 2015 - 06:55 PM
I am making a music program similar to FL studio (much simpler of course) and in it I have a timeline and different tracks represented as lines drawn with paintutils. When you click somewhere on a track it will put 1 tick worth of sound at that position and I need both the position and the value(as you have different sounds) to be stored in a table. At first I thought I could use keys to act as a position reference but I soon realised that if I am to add other keys in between keys it will mess up badly and I need the table to be recalled later to draw out a saved song. If anyone wants to take a look at my code - http://pastebin.com/jvFwMZGc P.S It's quite long and messy! If anyone wants to try out the program themselves addKey() is the unfinished function and it is called in clickDetect() you can just "–" comment it. You'd need a maxed out monitor connected via a modem and you'd need to change the peripheral.wrap to whatever name your monitor is. Here is a pic of how it looks like as of the moment:
https://gyazo.com/f9c3b34a4f4997601e997c4e847d1573

Thank you in advance!
HPWebcamAble #2
Posted 27 August 2015 - 11:57 PM
I believe this is what you are looking for:


local track1 = {}

--# Add sound at position 10
track1[10] = "soundValue"

--# Add another sound at position 4
track1[4] = "anotherSound"
If each track can have multiple sounds at one position, you'll need to store a table at each position, instead of just a single value.

In fact, you can condense this code a TON but using more tables.
Instead of 'track1','track2','track3', ect, you'd just have:

local tracks = {}
tracks[1] = {} --# If you don't make each sub track a new table, it'll error when you try to put a value in it.

tracks[1][4] = "sound" --# In the 1st track, but "sound" at position 4

Also, note that 'sparse' tables may or may not be in any order.
Non sparse tables will always be ordered.

local sparseTable = { ["bob"] = "hi" , ["jane"] = "hello" , ["SomeoneElse"] = "anotherthing" } --# Using 'pairs' on this table can return them in any order - you don't know before hand

local nonSparse = { "hi" , "hello" , "anotherthing" } --# When using the ordered-respecting 'ipairs', this table will be returned in the correct order.
No, 'ipairs' won't correctly return the first table's contense.


TLDR;
SpoilerOk, that was a little long. Basically, store your values like I show in the first code example, and use ipairs instead of pairs in for-loops
Edited on 27 August 2015 - 09:59 PM
LubsonGG #3
Posted 28 August 2015 - 07:35 AM
Thanks for the response! Some things about tables are a bit confusing for me like for example is there a difference when adding keys with table.insert or normally like you showed me.

local tracks = {}
tracks[1] = {}
tracks[1][100] = "sound" -- adding a sound at key 100
tracks[1][50] = "sound2" -- adding a sound at key 50

Does this mean key 50 will be added after key 100? If not, does it mean key 50 will be added before key 100 and if so would key 100 become 101 like table.insert does?

Also another way I was thinking of doing this: two tables would be added to each key in a track to store both position and sound. This way it would not matter what order the keys are set as long as there is a positon value that can be referenced.
Bomb Bloke #4
Posted 28 August 2015 - 08:16 AM
Whether or not table.insert() moves other indexes in the table depends on whether the indexes you target are already occupied. Performing direct assignments (without using table.insert()) means that if you target an index that is already in use, then it's associated value will simply be replaced, without affecting other indexes.

table.insert() furthermore aims to fill gaps. If you insert a value at [100] and then one at [50], then the one at [100] will stay in position unless [50], [51], [52] etc (all the way through to [99]) were already in use.

If you call table.insert() without specifying a parameter, then the first index with a nil value is the one that gets filled. That may or may not come after the highest index actually in use.

#myTable returns the highest index in your table before a nil value is encountered. table.maxn(myTable) returns the highest non-nil index, full-stop, but executes slower and usually isn't needed.
LubsonGG #5
Posted 28 August 2015 - 08:22 AM
Thank you! That clarifies quite a bit. I think I've managed to work it out.
HPWebcamAble #6
Posted 28 August 2015 - 11:42 PM
#myTable returns the highest index in your table before a nil value is encountered. table.maxn(myTable) returns the highest non-nil index, full-stop, but executes slower and usually isn't needed.

Also, 'table.maxn' was removed in Lua 5.2, so it won't be available in future CC releases.
Bomb Bloke #7
Posted 29 August 2015 - 01:52 AM
One of the first things I plan to "patch" back in if that happens, yes.

function table.maxn(myTable)
	local maxn = 0
	for key, _ in pairs(myTable) do if type(key) == "number" and key > maxn then maxn = key end end
	return maxn
end