Reputation: 1183
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
Upvotes: 3
Views: 1325
Reputation: 9183
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;
}
Upvotes: 0
Reputation: 3614
<?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));
Upvotes: 3
Reputation: 436
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;
}
Upvotes: 2