3

I've spent a while trying to get what I need from old answers but haven't quite got it (have got close though!).

I have this;

[January] => Array
 (
 [Tuesday] => Array
 (
 [foo] => Array
 (
 [82] => 47731
 [125] => 19894
 )
 [bar] => Array
 (
 [82] => 29911
 [125] => 10686
 )
 )
 }

...and I want this;

[0] => Array
 (
 'key' => 'January'
 'children' => Array
 [0] => Array 
 {
 'key' => 'Tuesday'
 'children' => Array 
 [0] => Array 
 {
 'key' => 'foo'
 'values' => Array
 {
 [82] => 47731
 [125] => 19894
 }
 [1] => Array
 {
 'key' => 'bar'
 'values' => Array
 {
 [82] => 29911
 [125] => 10686
 }
 }
 )
 }

I've got fairly close by adapting the first answer from Recursively change keys in array but only the bottom layer of my result is correct - the nodes with keys 'Tuesday', 'foo' and 'bar' just look the same as in the source array.

Here's what I've got so far;

public function transform_hierarchical_output(&$var)
{ 
 if (is_array($var)) 
 {
 $final = [];
 $i = 0;
 foreach ($var as $k => &$v) 
 {
 $new_node = [
 'key' => $k,
 'children' => $v
 ];
 $k = $i;
 $this->transform_hierarchical_output($v);
 $final[$k] = $new_node;
 $i++;
 }
 $var = $final;
 } 
 elseif (is_string($var)) 
 {
 }
}

This needs to work with a source array of any length and depth.

Thanks in advance.

Geoff

asked Apr 25, 2015 at 5:52
2
  • Why values for foo's and bar's children, but children for others? Any logic here? Commented Apr 25, 2015 at 6:01
  • Eventually every node will want a set of values but I thought I'd leave that out for now! Commented Apr 25, 2015 at 6:29

3 Answers 3

3
<?php
$array = [
 'January' => [
 'Tuesday' => [
 'foo' => [
 82 => 47731,
 125 => 19894,
 ],
 'bar' => [
 82 => 47731,
 125 => 19894,
 ]
 ]
 ]
];
function transform(array $input)
{
 $output = [];
 foreach ($input as $key => $val) {
 if (is_array(array_values($val)[0])) { // if next depth is an array
 $output[] = [
 'key' => $key,
 'children' => transform($val)
 ];
 } else {
 $output[] = [
 'key' => $key,
 'values' => $val
 ];
 }
 }
 return $output;
}
print_r(transform($array));
answered Apr 25, 2015 at 6:27

Comments

2

try below:

function t($arr)
 {
 $a = [];
 $num = 0;
 foreach($arr as $k => $v) {
 if (is_array($v))
 {
 $a[$num] = [
 'key' => $k,
 ];
 $a[$num][is_array(array_values($v)[0]) ? 'children' : 'values'] = t($v);
 $num ++;
 } else {
 $a[$k] = $v;
 }
 }
 return $a;
 }
answered Apr 25, 2015 at 6:19

Comments

0

First thing I should note is that, though there are many recursions in your example, but technically it is not a recursive loop in terms of the need for a self-executing function. Because your loop's scheme fluctuates a bit in its depth, it does not follow a regular pattern down to is last node; however it is a logical scheme, but is not repeated down to is last node.

The following function might work for you:

function doArray($array)
{
 $keys = array_keys($array);
 $arr_count = count($keys);
 $new_array;
 for($i = 0; $i < $arr_count; $i++)
 {
 $new_array[$i]["key"] = $keys[$i];
 $new_keys = array_keys($array[$keys[$i]]);
 for($w = 0; $w < count($new_keys); $w++)
 {
 $new_array[$i]["children"][$w]["keys"] = $new_keys[$i];
 $new_array[$i]["children"][$w]["children"] = array();
 for($w = 0; $w < count($new_keys); $w++)
 {
 $new_new_keys = array_keys($array[$keys[$i]][$new_keys[$w]]);
 for($q = 0; $q < count($new_new_keys); $q++)
 {
 $new_array[$i]["children"][$w]["children"][$q]["key"] = $new_new_keys[$q];
 //$new_array[$i]["children"][$w]["children"][$q]["children"] = $array[$keys[$i]][$new_keys[$w]][$new_new_keys[$q]];
 $last_new_keys = array_keys($array[$keys[$i]][$new_keys[$w]][$new_new_keys[$q]]);
 for($s = 0; $s < count($last_new_keys); $s++)
 {
 $new_array[$i]["children"][$w]["children"][$q]["values"][$last_new_keys[$s]] = $array[$keys[$i]][$new_keys[$w]][$new_new_keys[$q]][$last_new_keys[$s]];
 }
 }
 }
 }
 }
 return $new_array;
}
answered Apr 25, 2015 at 6:55

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.