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

[SOLVED] problem with values in array

Started by OniNoSeishin, 15 March 2012 - 07:31 PM
OniNoSeishin #1
Posted 15 March 2012 - 08:31 PM
Here's the piece of code with problems (it's inside a function):


for x = 1, #clients do
				data = separate(clients[x], ">") -- return in 'data' an array of strings; clients[x] is the original string, '>' is the separator [this one works]
				result[tonumber(data[1])] = {}
				result[tonumber(data[1])][tonumber(data[2])] = data[3]
			end
			
			return result
end

in my test it should be a 1x3 array, with this value:

[0][1] = 'test1'
[0][2] = 'test2'
[0][3] = 'test3'

the problem is that [0][1] and [0][2] are instead empty strings.
I tested further, with only 2 elements, and this time [0][1] was empty and [0][2] was ok ('test2'), so i can say that only the last value is inserted correctly in the array

So, how do i insert correctly values in my array?
Liraal #2
Posted 15 March 2012 - 08:42 PM
try
table.insert(table,value)
OniNoSeishin #3
Posted 15 March 2012 - 09:28 PM
tried:


for x = 1, #clients do
    data = separate(clients[x], ">")
    result[tonumber(data[1])] = {}
    table.insert(result[tonumber(data[1])], tonumber(data[2]), data[3])
end

still not working…
Espen #4
Posted 15 March 2012 - 10:35 PM
Can you give one example of the content of data[1], data[2] and data[3]?
OniNoSeishin #5
Posted 15 March 2012 - 10:51 PM
data[1] = '0'
data[2] = '1'
data[3] = 'test1'

so, clients[x] = "0>1>test1"

as an example. In successive iterations, the value in data[2] increases and the one in data[3] changes (for testing purposes, it's always 'testN')
Espen #6
Posted 15 March 2012 - 11:13 PM
I can't test it at the moment, but that does seem odd indeed.
What you could try, just to see if it changes anything:
If the first two values of the table that separate() returns are always numbers, then try to change separate so that it stores the numbers not as strings in the table, but actually as numbers.
So instead of { "2", "7", "test3" } have it look like { 2, 7, "test3 }

This way you shouldn't neet to transform data[1] and data[2] into numbers.
Now try to access the index of the result table with: result[data[1]]

Does that change anything?
OniNoSeishin #7
Posted 15 March 2012 - 11:44 PM
the fact is i didn't made the function "separate", i just pick it up from the internet, tested a while and started using it. I use it to split strings into strings in other parts of my code (which works good), so i can't force its return value.

Could the bidimensional array be the problem?

Actually i initialize the first dimension in the first line of my function:

result = {}

and then i initialize the second dimension inside the 'for' loop:


for x = 1, #clients do
	local data = separate(clients[x], ">")
	print(data[1].." "..data[2].." "..data[3])
	result[tonumber(data[1])] = {} -- HERE
	table.insert(result[tonumber(data[1])], tonumber(data[2]), tostring(data[3]))
end

then return the array
Espen #8
Posted 16 March 2012 - 11:19 AM
Hey OniNoSeishin,
I was able to play around with it now.
Since I don't have the code for separate(), I made an dummy one which simulates splitting values for two specific client-values.
This is the test code I used:

local result = {}
local clients = { "0>1>test3", "1>7>test5" }

-- Simulates splitting for two specific client-contents.
local function separate(tInput, sSep)
  if tInput == "0>1>test3" then
	return { "0", "1", "test3" }
  else
	return { "1", "7", "test5" }
  end
end

for x = 1, #clients do
  local data = separate(clients[x], ">")
  print(data[1].." "..data[2].." "..data[3])
  result[tonumber(data[1])] = {} -- HERE

  result[tonumber(data[1])][1] = data[1]
  result[tonumber(data[1])][2] = data[2]
  result[tonumber(data[1])][3] = data[3]
end

print("Result[0][1]: "..tostring(result[0][1]))
print("Result[0][2]: "..tostring(result[0][2]))
print("Result[0][3]: "..tostring(result[0][3]))
print()
print("Result[1][1]: "..tostring(result[1][1]))
print("Result[1][2]: "..tostring(result[1][2]))
print("Result[1][3]: "..tostring(result[1][3]))

Hope this helps, cheers. :D/>/>
Edited on 16 March 2012 - 10:34 AM
OniNoSeishin #9
Posted 16 March 2012 - 12:10 PM
i tested your code with my separate function and it works, but i need it to be:

result[data[1]][data[2]] = data[3]

data[1] and data[2] are the 'x' and 'y', and data[3] is the content

here's my separate function:
Spoiler

function separate(string, divider)
    local function find(string, match, startIndex)
        if not match then return nil end
        _ = startIndex or 1
        local _s = nil
        local _e = nil
        _len = match:len()
        while true do
            _t = string:sub( _ , _len + _ - 1)
            if _t == match then
                _s = _
                _e = _ + _len - 1
                break
            end
            _ = _ + 1
            if _ > string:len() then break end
        end
        if _s == nil then return nil else return _s, _e end
    end

    if not divider then return nil end
    local start = {}
    local endS = {}
    local n=1
    repeat
        if n==1 then
            start[n], endS[n] = find(string, divider)
        else
            start[n], endS[n] = find(string, divider, endS[n-1]+1)
        end
        n=n+1
    until start[n-1]==nil
    local subs = {}
    for n=1, #start+1 do
        if n==1 then
            subs[n] = string:sub(1, start[n]-1)
        elseif n==#start+1 then
            subs[n] = string:sub(endS[n-1]+1)
        else
            subs[n] = string:sub(endS[n-1]+1, start[n]-1)
        end
    end
    return subs
end
Espen #10
Posted 16 March 2012 - 12:32 PM
Ok, I've changed the code accordingly and also fixed the values being empty in your previous tries.
It was really *derp* when I finally recognized it.^^

Here's the noew code (I left the separate function out):
Spoiler

local result = {}
local clients = { "0>1>test01", "0>2>test02", "0>3>test03", "1>1>test11", "1>2>test12", "1>3>test13", "2>1>test21", "2>2>test22", "2>3>test23" }

for x = 1, #clients do
  local data = separate(clients[x], ">")
  print(data[1].." "..data[2].." "..data[3])

  if result[tonumber(data[1])] == nil then
	result[tonumber(data[1])] = {}
  end

  result[tonumber(data[1])][tonumber(data[2])] = data[3]
end

print("Result[0][1]: "..tostring(result[0][1]))
print("Result[0][2]: "..tostring(result[0][2]))
print("Result[0][3]: "..tostring(result[0][3]))
print()
print("Result[1][1]: "..tostring(result[1][1]))
print("Result[1][2]: "..tostring(result[1][2]))
print("Result[1][3]: "..tostring(result[1][3]))
print()
print("Result[1][1]: "..tostring(result[2][1]))
print("Result[1][2]: "..tostring(result[2][2]))
print("Result[1][3]: "..tostring(result[2][3]))

So the main change is changing this…

result[tonumber(data[1])] = {}
… to this …

if result[tonumber(data[1])] == nil then
  result[tonumber(data[1])] = {}
end
This guarantees that an already defined table won't be cleared again.
Edited on 16 March 2012 - 11:35 AM
Casper7526 #11
Posted 16 March 2012 - 12:38 PM
result[tonumber(data[1])] = result[tonumber(data[1])] or {}
Espen #12
Posted 16 March 2012 - 12:50 PM
Thanks Casper, I'm in kind of a code-noise moment, where every line of code seems to melt in with the next. :
Really need to get some sleep, didn't go to bed last night. Too many interesting things to do, damn sleepy body! :D/>/>
Casper7526 #13
Posted 16 March 2012 - 12:53 PM
Well, like I always say, code should really only matter to you in the most parts. You want to write code that YOU can understand and YOU can debug and YOU can follow :D/>/>

So if it takes you 5 lines of code to do something that someone else can do in 1 line of code, but you can read and follow your way better. Then definitely use your way over theirs!
Espen #14
Posted 16 March 2012 - 02:02 PM
No, I meant thanks for reminding me of the a = b or c part. I usually use it myself, especially when trying to optimize code I'm finished with.
It was just that I derped quite a few times with OniNoSeishin's code, because I pulled an all-nighter. And the more tired I get, the more code looks like mush.
it's like becoming a mental zombie, forgetting how to write efficient code, how to make it as dynamic as possible, etc.
But I agree that in general it shouldn't matter, as long as it works. And if the code is useful and dynamic enough then there's bound to be someone making the code more efficient.^^

Gosh, it's like a drug, why am I still sitting infront of the monitor!? Going to take a nap now. Really. :D/>/>
OniNoSeishin #15
Posted 16 March 2012 - 05:38 PM
@Espen: i completely understand you, in fact i didn't realize i was keeping clearing the table on each 'for' iteration! God, i hate when i'm so blinded. Thank you so much, i was going crazy xD

@Casper: thanks for the 'a = b or c' tip, i didn't know it even exists! I'll start using it ASAP