Hi,

I have a database query returning the following array structure;

Array
(
    [0] => Array
        (
            [Category] => Array
                (
                    [id] => 9
                    [name] => ABC
                )

        [Ds] => Array
            (
                [ds_id] => 39
            )

    )

[1] => Array
    (
        [Category] => Array
            (
                [id] => 10
                [name] => DEF
            )

       [Ds] => Array
            (
                [ds_id] => 40
            )

    )

)

I need to change the structure of the array(to feed a json object) to this (dynamically);

Array
(
    [0] => Array
        (
           [id] => 9
           [name] => ABC
           [ds_id] => 39
         )

[1] => Array
    (
       [id] => 10
       [name] => DEF
       [ds_id] => 40
     )

)

I am embarassed to say i have spent the best part of two days mucking around with a multitude of recursive functions to no avail. At best i completely flatten the array at worst i end up with a complete mishmash.

I tried to set up a php debugger to watch the process but after 3 days of trying i came to the conclusion it was not compatible with my working environment. I am still using php 4.4.9.
Any assistance would be greatly appreciated.

    First off, you should not need to change it, provided you have the possibility of changing the javascript code. After you eval the response object client side

    // assuming the evaled object is in a variable called data
    for (var i = 0; i < data.length; ++i) {
    	var id = data[i].Category.id;
    	var name = data[i].Category.name;
    	var ds_id = data[i].Ds.ds_id;
    
    // Make use of the above...
    }

    Else, if you really want to change the structure, there's no need using recursion. All you need is a loop

    // Once again assuming your array is in a var called $data
    for ($i = 0; $i < count($data); ++$i) {
    	$id		= $data[$i]['Category']['id'];
    	$name	= $data[$i]['Category']['name'];
    	$ds_id	= $data[$i]['Ds']['ds_id'];
    
    $data[$i] = array("id" => $id, "name" => $name, "ds_id" => $ds_id);
    }
    
      johanafm;10924443 wrote:

      First off, you should not need to change it, provided you have the possibility of changing the javascript code. After you eval the response object client side

      // assuming the evaled object is in a variable called data
      for (var i = 0; i < data.length; ++i) {
      	var id = data[i].Category.id;
      	var name = data[i].Category.name;
      	var ds_id = data[i].Ds.ds_id;
      
      // Make use of the above...
      }

      Else, if you really want to change the structure, there's no need using recursion. All you need is a loop

      // Once again assuming your array is in a var called $data
      for ($i = 0; $i < count($data); ++$i) {
      	$id		= $data[$i]['Category']['id'];
      	$name	= $data[$i]['Category']['name'];
      	$ds_id	= $data[$i]['Ds']['ds_id'];
      
      $data[$i] = array("id" => $id, "name" => $name, "ds_id" => $ds_id);
      }
      

      thanks johanafm - i forgot to mention that the keys in the array can change , and possibly the arrays too maybe deeply nested - i posted what was what i thought was a simpler view.

      #  function test ($data = null, $key = null){
      # $key;
      # foreach ($data as $k => $v){
      # if(is_array($v){
      # if(is_numeric($k){ $key = $k;}
      # $this->test($v, $key);
      # }else{
      # echo "$key:::$k:::$v\n";
      # }
      # }
      

      The echo out will iterate through the array with:
      0:🆔:9
      0::name::ABC
      0::ds_id::41
      etc

      I just have to build a multi dim result set - and my mind has gone blank - i have sprinled the code with array_merge, array_push.

        See if this does what you need:

        /**
         * Convert a n-dim array to a 1-dim array
         * @param array $arr
         * @return array
         */
        function flatten($arr)
        {
           $return = array();
           foreach($arr as $key => $val)
           {
              if(is_array($val))
              {
                 $ret = flatten($val);
                 $return = $return + $ret;
              }
              else
              {
                 $return[$key] = $val;
              }
           }
           return $return;
        }
        
        // USAGE:
        foreach($array as $key => $val)
        {
           $array[$key] = flatten($val);
        }
        

          Just setting up some test data...

          $data = array(
          			"Category" => array(
          				"id"	=> 2,
          				"name"	=> "car"
          			),
          			"Ds" => array(
          				"ds_id" => 7,
          				"content" => array(
          					"title"	=> "Bla bla bla",
          					"desc"	=> "Lots of bla bla bla",
          					"name"	=> "another name"
          				)
          			)
          		);
          

          And very simple code to create a completely flat array.

          function flatten($data, &$flat = array()) {
          	foreach ($data as $k => $el) {
          		if (is_array($el)) {
          			 flatten($el, $flat);
          		}
          		else {
          			/* In case you need to deal with the possibility of keys on different levels,
          				being the same, this part renames them to "key", "key2", "key3" */
          			if (array_key_exists($k, $flat)) {
          				$i = 2;
          				while (array_key_exists($k.$i, $flat))
          					$i = intval($i) + 1;
          			}
          			else
          				$i = "";
          
          		$flat[$k.$i] = $el;
          	}
          }
          }
          
          $flat = array();
          flatten($data, $flat);
          print_r($flat);
          

          And in case you want a 2-dimensional array like you said,

          foreach ($topLevelArray as $k => $el) {
          	if (is_array($el))
          		$topLevelArray[$k] = flatten($el);
          }

            Thanks NogDog and johanafm for your efforts - they work, really appreciated - i was close, just couldn't see that last mile.

              Write a Reply...