ArraySerialize

Revision as of 20:37, 3 July 2010 by imported>QQuix (Typos)

A User Function for use with Oblivion Script Extender

Syntax:

ArraySerialize Arrayarray, Prefixstring

Serializes a multi-dimensional array into a one-dimension StringMap array.

The arguments are:

  • Array - the array to serialize
  • Prefix - used in recursion

An array like this:

['EntryA']
= ['Attr1'] = 'A' 
= ['Attr2'] 
= = [0] 
= = = ['Value1'] = 11
= = = ['Value2'] = 22
= = [1] 
= = = ['Value1'] = 1111
= = = ['Value2'] = 2222
['EntryB']
= ['Attr1'] = 'B'
= = = . . . etc

Will become:

['EntryA_Attr1'] = 'A' 
['EntryA_Attr1_0_Value1'] = 11
['EntryA_Attr1_0_Value2'] = 22
['EntryA_Attr1_1_Value1'] = 1111
['EntryA_Attr1_1_Value2'] = 2222
['EntryB_Attr1'] = 'B' 
. . . etc


Notes

  • A serialized array is useful for storing array data in external media (like a Pluggy INI file)
  • Keys from Map type arrays will be formatted with a decimal point to differentiate them from Array type arrays when converting the serialized array back to its original multi-dimensional structure.
  • The code uses the underscore ('_') as the concatenating char and assumes that it will not be present in any array key or value. Change it to another char if you have underscores in your arrays.
  • The function is recursive, therefore limited to OBSE's maximum of 30 nested function calls.


Usage

Call ArraySerialize MyArray ""

The first call should have a null 'Prefix' attribute (unless you want to prepend a literal to all your keys)

Code

scriptname ArraySerialize

array_var arInput 
array_var asEntry
array_var asEntry2
array_var asSerial 
array_var asTemp
string_var sKey
string_var sPrefix 

begin Function {arInput sPrefix }
 
   ;=== Initialize the return array ===
   let asSerial := ar_construct stringmap

   ;=== Concatenate the prefix ===
   if eval sPrefix != ""
       let sPrefix := sPrefix + "_"
   endif	
 
   foreach asEntry <- arInput 
       ;=== Prepare current key ===
       if eval (typeof asEntry[key]) == "String"
           let sKey := asEntry[key]
       elseif eval (typeof asEntry[key]) ==  "Number"
           let sKey := $asEntry[key]
           if eval (typeof arInput ) ==  "Map"
               if eval (sv_Find "." sKey ) < 0
                   let sKey  := sKey + ".0"		 		    
               endif
           endif
       endif

       ;=== Append to prefix ===
       let sKey := sPrefix + sKey 

       ;=== Set the value===
       if eval (typeof asEntry[value]) == "String"
           let asSerial[sKey] := asEntry[value]
       elseif eval (typeof asEntry[value]) ==  "Number"
           let asSerial[sKey] := asEntry[value]
       elseif eval (typeof asEntry[value]) ==  "Form"
           let asSerial[sKey] := asEntry[value]
       else
           ;=== Or serialize the next array level ===
           let asTemp := call zuArraySerialize asEntry[value] sKey 

           ;=== Add rntries to array ===
           foreach asEntry2 <- asTemp 
               let asSerial[asEntry2[key]] := asEntry2[value]
           loop

       endif
   loop

   SetFunctionValue asSerial

   sv_destruct sKey sPrefix
end

See Also