Thursday, September 8, 2011

Javascript Multi-Dimension Array to JSON Converter

The Problem
Lately ask by one of my programmer - How to pass a javascript multi-dimension array back to PHP? First thing strike in my mind, JSON.stringify! But after some quick reading and testing, found out that stringify does not support cyclic data structures.

Then brainstorming session begin. Why need to pass in multi-dimension array, why not this and why not that... And last, he just said "This is the way I want, can you make it happen or not?".

Thanks for his challenge, here by is the solution.



The Solution
Following code is tested with following scenario

  1. string
  2. numeric
  3. fraction
  4. boolean
  5. \r\n 
Is not yet fully comply to json specification yet but support most common use datatype. If anyone enhance this code, please do share. Thank you.




<script>         
    /**
     * Convert an javascript array to json format, support multi 
     * dimension array.
     *
     * @param    thearray   Javascript array wish to convert
     * @return       JSON   JSON String represent the array
     */
    function multiDimensionArray2JSON(thearray)
    {
        var output = '';
        var opentag = '';
        var closetag ='';

        /* Only process if user input is an array */
        if (thearray instanceof Array)
        {   
            var arraykey = [];
            var keyneeded = false;

            /* Get the key, if the key is non numeric then will output 
             * the key */
            for (var key in thearray)
            {
                if (thearray[key] != undefined)
                {
                    arraykey.push(key);      
                    if (!/^[0-9]*$/.test(key))
                    {
                        keyneeded = true;
                    }
                }
            }

            /* use difference tag for associate array */
            if (keyneeded)
            {
                opentag = '{';
                closetag ='}';                
            }
            else
            {
                opentag = '[';
                closetag =']';                  
            }

            output += opentag;

            for (var i = 0; i < arraykey.length; i++)
            {
                /* insert key */
                if (keyneeded)
                {
                    output += '"'+arraykey[i]+'":';
                }

                /* if sub node still a array then process it */
                if (thearray[arraykey[i]] instanceof Array)
                {
                    output += multiDimensionArray2JSON(thearray[arraykey[i]]);
                }
                else
                {
                    /* if string, quoate it */
                    if (typeof thearray[arraykey[i]] == 'string')
                    {
                        output += '"'+thearray[arraykey[i]].replace(/\n/, '\\n').replace(/\r/, '\\r')+'"';
                    }
                    else
                    {
                        output += thearray[arraykey[i]];
                    }                            
                }

                /* end of element, terminate it */
                if ((i+1) != arraykey.length)
                {
                    output += ',';
                }
            }   
            output += closetag;     
        }
        else
        {
            output += '"'+thearray+'"';
        }                            

        return output;
    }       
</script>



The Test Output

Associate Array

PHP json encode: {"first":["child1","node1",["subchidl1","subnode1"]],"second":{"0":"child2","1":"node3","new":true},"third":["child3",3,3.33,"a\r\n"],"forth":"child4"} (PHP json encode)

{"first":["child1","node1",["subchidl1","subnode1"]],"second":{"0":"child2","1":"node3","new":true},"third":["child3",3,3.33,"a\r\n"],"forth":"child4"} (multiDimensionArray2JSON)

Normal Array

PHP json encode: [["child1","node1",["subchidl1","subnode1"]],{"0":"child2","1":"node3","new":true},["child3","node3"],"child4"] (PHP json encode)

[["child1","node1",["subchidl1","subnode1"]],{"0":"child2","1":"node3","new":true},["child3","node3"],"child4"] (multiDimensionArray2JSON)

Not Array

PHP json encode: "not array" (PHP json encode)
"not array" (multiDimensionArray2JSON)

Masza

{"carrier0":["","10"],"carrier1":["10","10"],"0carrier":["","10"],"1carrier":["10","10"]} (PHP json encode)

{"carrier0":["","10"],"carrier1":["10","10"],"0carrier":["","10"],"1carrier":["10","10"]} (multiDimensionArray2JSON)         

To download the test scrip, click here.         


2 comments: