Author Topic: problem with serialize  (Read 5975 times)

0 Members and 1 Guest are viewing this topic.

Offline blackwings

  • Scripter
  • King
  • ******
  • Posts: 986
  • Karma: +12/-8
problem with serialize
« 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 =
Code: [Select]
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 =
Code: [Select]
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 =
Code: [Select]
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 =
Code: [Select]
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


PtokaX forum

problem with serialize
« on: 15 September, 2005, 18:15:14 »

Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #1 on: 15 September, 2005, 18:26:31 »
Do nothing, they are both the same.
Everything could have been anything else and it would have just as much meaning.

Offline blackwings

  • Scripter
  • King
  • ******
  • Posts: 986
  • Karma: +12/-8
(No subject)
« Reply #2 on: 15 September, 2005, 19:25:01 »
Quote
Originally 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  :)


Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #3 on: 15 September, 2005, 20:33:27 »
It would be terrible to determine, maybe you can do some table.getn on it or similar.
Everything could have been anything else and it would have just as much meaning.

Offline blackwings

  • Scripter
  • King
  • ******
  • Posts: 986
  • Karma: +12/-8
(No subject)
« Reply #4 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 =
Code: [Select]
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


Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #5 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.
Everything could have been anything else and it would have just as much meaning.

Offline blackwings

  • Scripter
  • King
  • ******
  • Posts: 986
  • Karma: +12/-8
(No subject)
« Reply #6 on: 15 September, 2005, 23:12:36 »
Quote
Originally 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?


Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #7 on: 16 September, 2005, 00:25:09 »
table.getn is only valid for arrays. It returns 0 for associative tables.
Everything could have been anything else and it would have just as much meaning.

Offline blackwings

  • Scripter
  • King
  • ******
  • Posts: 986
  • Karma: +12/-8
(No subject)
« Reply #8 on: 16 September, 2005, 01:19:51 »
Quote
Originally 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?
« Last Edit: 16 September, 2005, 01:20:16 by blackwings »


Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #9 on: 16 September, 2005, 01:52:25 »
I thought these hints would be enough. See this page .
Everything could have been anything else and it would have just as much meaning.

Offline blackwings

  • Scripter
  • King
  • ******
  • Posts: 986
  • Karma: +12/-8
(No subject)
« Reply #10 on: 16 September, 2005, 02:38:33 »
Quote
Originally posted by bastya_elvtars
I thought these hints would be enough. See this page .
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  :(


Offline Pothead

  • Lord
  • ***
  • Posts: 455
  • Karma: +25/-4
(No subject)
« Reply #11 on: 16 September, 2005, 02:42:51 »
Quote
Originally posted by bastya_elvtars
I thought these hints would be enough. See this page .
Thanks. :) I was just looking for some explaination of LUA tables.

Also thanks Plop and bastya_elvtars , for writing these How-To's. :)
« Last Edit: 16 September, 2005, 02:50:08 by Pothead »

Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #12 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.
Everything could have been anything else and it would have just as much meaning.

Offline Pothead

  • Lord
  • ***
  • Posts: 455
  • Karma: +25/-4
(No subject)
« Reply #13 on: 16 September, 2005, 03:26:29 »
Quote
Now 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 ?
Quote
But 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.
Code: [Select]
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 ? :)
« Last Edit: 16 September, 2005, 03:42:11 by Pothead »

Offline blackwings

  • Scripter
  • King
  • ******
  • Posts: 986
  • Karma: +12/-8
(No subject)
« Reply #14 on: 16 September, 2005, 04:18:01 »
ehm, I think you meant soomething like this, but I didn't get it quite right =
Code: [Select]
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


Offline Pothead

  • Lord
  • ***
  • Posts: 455
  • Karma: +25/-4
(No subject)
« Reply #15 on: 16 September, 2005, 12:39:42 »
thanks Mutor. :)
*passes the j* ;)

Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #16 on: 16 September, 2005, 14:37:38 »
Quote
Originally posted by Mutor
Code: [Select]
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:
Code: [Select]
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.:

Code: [Select]
> 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. :-)
« Last Edit: 16 September, 2005, 14:38:34 by bastya_elvtars »
Everything could have been anything else and it would have just as much meaning.

Offline Pothead

  • Lord
  • ***
  • Posts: 455
  • Karma: +25/-4
(No subject)
« Reply #17 on: 17 September, 2005, 00:23:01 »
Well both ways of doing it are a vast improvement than my suggestion.  :)

Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #18 on: 17 September, 2005, 00:25:36 »
Quote
Originally posted by Mutor
Quote
You 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.
Everything could have been anything else and it would have just as much meaning.

Offline Pothead

  • Lord
  • ***
  • Posts: 455
  • Karma: +25/-4
(No subject)
« Reply #19 on: 17 September, 2005, 01:36:00 »
As an alternative way (one not doing a for loop through the whole table), would this work ?
Code: [Select]
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.
« Last Edit: 17 September, 2005, 01:39:01 by Pothead »

Offline bastya_elvtars

  • Forum God
  • ****
  • Posts: 3 744
  • Karma: +173/-7
  • The rock n' roll doctor
    • The FreshStuff3 Site
(No subject)
« Reply #20 on: 17 September, 2005, 02:23:51 »
Quote
Originally posted by Pothead
As an alternative way (one not doing a for loop through the whole table), would this work ?
Code: [Select]
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.

Code: [Select]
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.
« Last Edit: 17 September, 2005, 02:39:51 by bastya_elvtars »
Everything could have been anything else and it would have just as much meaning.

PtokaX forum

(No subject)
« Reply #20 on: 17 September, 2005, 02:23:51 »