PtokaX forum

Development Section => Your Developing Problems => Topic started by: blackwings on 15 September, 2005, 18:15:14

Title: problem with serialize
Post by: blackwings on 15 September, 2005, 18:15:14
I have a small problem with serialize, so please, can anyone help?!
I have a table looking like this = sText1 = "text1"
sText2 = "text2"
sText3 = "text3"

rTable = {
[1] = {sText1,sText2,sText3},
[2] = {vTable[1][1],vTable[1][2],vTable[1][3]},
[3] = {vTable[2][1],vTable[2][2],vTable[2][3]},
[4] = {vTable[3][1],vTable[3][2],vTable[3][3]},
[5] = {vTable[4][1],vTable[4][2],vTable[4][3]},
}
Which with the serialize code at the bottom of this post, gives this result = cTable = {
[1] = {
[1] = "text1",
[2] = "text2",
[3] = "text3",
},
[2] = {
[1] = "text4",
[2] = "text5",
[3] = "text6",
},
[3] = {
[1] = "text7",
[2] = "text8",
[3] = "text9",
},
[4] = {
[1] = "text10",
[2] = "text11",
[3] = "text12",
},
[5] = {
[1] = "text13",
[2] = "text14",
[3] = "text15",
},
}
But I want it to be like this = cTable = {
[1] = {text1,text2,text3},
[2] = {text4,text5,text6},
[3] = {text7,text8,text9},
[4] = {text10,text11,text12},
[5] = {text13,text14,text15},
}
So what should I do?
Here is the serialze code I use = function Serialize(tTable, sTableName, sTab)
assert(tTable, "tTable equals nil");
assert(sTableName, "sTableName equals nil");
assert(type(tTable) == "table", "tTable must be a table!");
assert(type(sTableName) == "string", "sTableName must be a string!");

sTab = sTab or "";
sTmp = ""

sTmp = sTmp..sTab..sTableName.." = {\n"

for key, value in tTable do
local sKey = (type(key) == "string") and string.format("[%q]",key) or string.format("[%d]",key);
if(type(value) == "table") then
sTmp = sTmp..Serialize(value, sKey, sTab.."\t");
else
local sValue = (type(value) == "string") and string.format("%q",value) or tostring(value);
sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
end
sTmp = sTmp..",\n"
end
sTmp = sTmp..sTab.."}"
return sTmp
end


function SaveToFile(file , table , tablename)
local handle = io.open(file,"w+")
handle:write(Serialize(table, tablename))
handle:flush()
handle:close()
end
Title:
Post by: bastya_elvtars on 15 September, 2005, 18:26:31
Do nothing, they are both the same.
Title:
Post by: blackwings on 15 September, 2005, 19:25:01
QuoteOriginally posted by bastya_elvtars
Do nothing, they are both the same.
I know, but it looks nicer with the way I want it :P
+  that I have a function that backup the file its in and it the back folder would get as big if the filesize of each backup was smaller  :)
Title:
Post by: bastya_elvtars on 15 September, 2005, 20:33:27
It would be terrible to determine, maybe you can do some table.getn on it or similar.
Title:
Post by: blackwings on 15 September, 2005, 21:59:14
same thing with table.getn or maybe I did something wrong :P
If I didn't do anything wrong, then maybe it shouldn't be %q in string.format("[%q]",i).

here is the code = function Serialize(tTable, sTableName, sTab)
sTab = sTab or "";
sTmp = ""

sTmp = sTmp..sTab..sTableName.." = {\n"

for i = 1,table.getn(tTable) do
local sKey = (type(i) == "string") and string.format("[%q]",i) or string.format("[%d]",i);
if(type(tTable[i]) == "table") then
sTmp = sTmp..Serialize(tTable[i], sKey, sTab.."\t");
else
local sValue = (type(tTable[i]) == "string") and string.format("%q",tTable[i]) or tostring(tTable[i]);
sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
end
sTmp = sTmp..",\n"
end
sTmp = sTmp..sTab.."}"
return sTmp
end
Title:
Post by: bastya_elvtars on 15 September, 2005, 22:07:56
If table.getn >= 1 then you write out the values only. You will have to rewrite the serialisation routine, it will be slower as well.
Title:
Post by: blackwings on 15 September, 2005, 23:12:36
QuoteOriginally posted by bastya_elvtars
If table.getn >= 1 then you write out the values only. You will have to rewrite the serialisation routine, it will be slower as well.
ehm, I dont quite get what you mean :S could you explain more what you meant?
Title:
Post by: bastya_elvtars on 16 September, 2005, 00:25:09
table.getn is only valid for arrays. It returns 0 for associative tables.
Title:
Post by: blackwings on 16 September, 2005, 01:19:51
QuoteOriginally posted by bastya_elvtars
table.getn is only valid for arrays. It returns 0 for associative tables.
when I said I wanted you to explain, I didn't mean why I should use "if table.getn >= 1",
but HOW I should use it, so how did you mean that I should use it?
Title:
Post by: bastya_elvtars on 16 September, 2005, 01:52:25
I thought these hints would be enough. See this page (http://ptxwiki.psycho-chihuahua.net/doku.php/scriptinghelp/tables) .
Title:
Post by: blackwings on 16 September, 2005, 02:38:33
QuoteOriginally posted by bastya_elvtars
I thought these hints would be enough. See this page (http://ptxwiki.psycho-chihuahua.net/doku.php/scriptinghelp/tables) .
I know how to use various types of arrays and tables. I asked how you meant I should use table.getn when it comes to the serialize function,
please stop talk in riddles, for you something might be obvious, but not to me atleast  :(
Title:
Post by: Pothead on 16 September, 2005, 02:42:51
QuoteOriginally posted by bastya_elvtars
I thought these hints would be enough. See this page (http://ptxwiki.psycho-chihuahua.net/doku.php/scriptinghelp/tables) .
Thanks. :) I was just looking for some explaination of LUA tables.

Also thanks Plop and bastya_elvtars , for writing these How-To's. :)
Title:
Post by: bastya_elvtars on 16 September, 2005, 02:44:30
In the serialize there is a check for a variable type. If the type is table, it uses a saving routine, now here you can further check whether that's an associative table or an array (in the 2nd case table.getn returns a number > 0). If array, you write in a different format.

I will NOT write the script for you.
Title:
Post by: Pothead on 16 September, 2005, 03:26:29
QuoteNow comes the hard part: Joe marries Natalie too, and has 2 wives. This is a crime, the punishment is having 2 mothers-in-law. Nevertheless, we should still be up-to-date. What should we do? Well, tables can also contain arrays (as well as any value). Let?s just see how we can include this miserable Joe:
wives["Joe"]={"Tina","Natalie"}
Can this be done by just adding the new value to existing table structure ?
QuoteBut Natalie is not a devoted one, so she divorces again. Handling this issue now invokes array-specific functions:
table.remove(wives["Joe"],2)
 ... and Natalie is history.
Anyway to do this without having a static interger variable. ?

E.g. something like this to remove wife Natalie from Joe.
for a table.getn(wives) do
if string.find("Joe", wives) then
for b in pairs(wives) do
if b["Natalie"] then
table.remove(wives[a],[b])
end
end
end
end

Or won't this work / or have i gone a really bad way about doing this ? :)
Title:
Post by: blackwings on 16 September, 2005, 04:18:01
ehm, I think you meant soomething like this, but I didn't get it quite right = function Serialize(tTable, sTableName, sTab)
sTab = sTab or "";
sTmp = ""

sTmp = sTmp..sTab..sTableName.." = {\n"

for i = 1,table.getn(tTable) do
local sKey = (type(i) == "string") and string.format("[%q]",i) or string.format("[%d]",i);
if (type(tTable[i]) == "table") then
if table.getn(tTable[i])>=1 then
table.insert(tTable[i], i,table.getn(tTable[i]))
else
sTmp = sTmp..Serialize(tTable[i], sKey, sTab.."\t");
end
else
local sValue = (type(tTable[i]) == "string") and string.format("%q",tTable[i]) or tostring(tTable[i]);
sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
end
sTmp = sTmp..",\n"
end
sTmp = sTmp..sTab.."}"
return sTmp
end
Title:
Post by: Pothead on 16 September, 2005, 12:39:42
thanks Mutor. :)
*passes the j* ;)
Title:
Post by: bastya_elvtars on 16 September, 2005, 14:37:38
QuoteOriginally posted by Mutor
for i,v in wives["Joe"] do
if v == "Natalie" then
table.remove(wives["Joe"],i)
end
end

 and pass the doobie, bogart  :P

You miss the point, we know what the table looks like.

@Mutor:
for i,v in pairs(wives["Joe"]) do
if v == "Natalie" then
table[i]=nil
end
end

Without a function call, it is faster. :P

BTW there is an inline discussion facility in the wiki. Here it will sooner or later be lost, but there you can post your alt. methods for this, and it will introduce more flavors in that document, so please use that.

Ex.:

> I like this method.
>> I don't.

-- // EDIT

@blackwings: I found an easier method. for k,v in table do; if tonumber(k) then this is an array. :-)
Title:
Post by: Pothead on 17 September, 2005, 00:23:01
Well both ways of doing it are a vast improvement than my suggestion.  :)
Title:
Post by: bastya_elvtars on 17 September, 2005, 00:25:36
QuoteOriginally posted by Mutor
QuoteYou miss the point, we know what the table looks like.

I didnt miss a point, I was merely repsonding to Pothead. You can tell that by the subject Pothead...

Ooops, clicked the wrong one, forgive me.
Title:
Post by: Pothead on 17 September, 2005, 01:36:00
As an alternative way (one not doing a for loop through the whole table), would this work ?
if (wives["Joe"]["Natalie"] ~= nil) then
      wives["Joe"]["Natalie"] = nil
end
*** Edit *** If this is good, only the middle line should be needed, for the particular example.  The other 2 lines are just as an error prevention check.
Title:
Post by: bastya_elvtars on 17 September, 2005, 02:23:51
QuoteOriginally posted by Pothead
As an alternative way (one not doing a for loop through the whole table), would this work ?
if (wives["Joe"]["Natalie"] ~= nil) then
      wives["Joe"]["Natalie"] = nil
end
*** Edit *** If this is good, only the middle line should be needed, for the particular example.  The other 2 lines are just as an error prevention check.

if wives["Joe"] and table.getn(wives["Joe"]) > 0 then
      wives["Joe"]["Natalie"] = nil
end

This way we just check if Joe is married at all. I will transport this discussion to the wiki. :)

- // EDIT

Added. Continue there please. (http://ptxwiki.psycho-chihuahua.net/doku.php/scriptinghelp/tables#checking_values_in_a_table)