Shift Recursive nested child array to parent array PHP - php

I have an issue with forming a recursive array. That is shifting the child array nodes to direct elements to a parent array.
like from,
Array
(
[0] => Array
(
[id] => 1
[category_name] => flare
[parent_category_id] => 0
[childrenrecursive] => Array
(
[0] => Array
(
[id] => 2
[category_name] => analytics
[parent_category_id] => 1
[braincount] => Array
(
[count] => 3
[category_id] => 2
)
[childrenrecursive] => Array
(
[0] => Array
(
[id] => 4
[category_name] => sports analytics
[parent_category_id] => 2
[braincount] => Array
(
[count] => 4
[category_id] => 4
)
[childrenrecursive] => Array
(
)
)
)
)
[1] => Array
(
[id] => 3
[category_name] => cluster
[parent_category_id] => 1
[braincount] => Array
(
[count] => 4
[category_id] => 3
)
[childrenrecursive] => Array
(
)
)
)
)
)
to,
Array
(
[0] => Array
(
[id] => 1
[category_name] => flare
[parent_category_id] => 0
[childrenrecursive] => Array
(
[0] => Array
(
[id] => 2
[category_name] => analytics
[parent_category_id] => 1
[count] => 3
[category_id] => 2
[childrenrecursive] => Array
(
[0] => Array
(
[id] => 4
[category_name] => sports analytics
[parent_category_id] => 2
[count] => 4
[category_id] => 4
[childrenrecursive] => Array
(
)
)
)
)
[1] => Array
(
[id] => 3
[category_name] => cluster
[parent_category_id] => 1
[count] => 4
[category_id] => 3
[childrenrecursive] => Array
(
)
)
)
)
)
only by moving following child array append to parent in a recursive way.
[braincount] => Array
(
[count] => 4
[category_id] => 3
)
can anybody help me to format the array like specified.

Let's say $input is the array posted in the question:
/**
* If $value is an array then move the content of 'braincount' one level up
* (in $value) then call recursively for all its children.
*/
function moveUp($value)
{
// Not an array? Nothing to do; return the input value unchanged
if (! is_array($value)) {
return $value;
}
// Move the content of 'braincount' (if present) one level up
if (array_key_exists('braincount', $value)) {
$value = array_merge($value, $value['braincount']);
unset($value['braincount']);
}
// Apply the same operation to all children
return array_map(__FUNCTION__, $value);
}
// Verify it works
print_r(moveUp($input));

Related

Flatten Array php

I'm trying to flat a multidimensional array to a given specific format.
I have a tree that is saved as a nested array, which is ok, but the function given to render the array in the UI expects only one array and, per each child, an independent array. Instead of the nested array, each option should be at the same level.
This is how my var_dump of my array:
(
[id] => 1
[name] => some data.
[emoji] => 🐕
[parent_id] =>
[children] => Array
(
[0] => Array
(
[id] => 2
[name] => Food
[emoji] => 🥩
[parent_id] => 1
[children] => Array
(
)
)
[1] => Array
(
[id] => 3
[name] => some other data
[emoji] => 😌
[parent_id] => 1
[children] => Array
(
[0] => Array
(
[id] => 4
[name] => Massages
[emoji] => 💆
[parent_id] => 3
[children] => Array
(
)
)
[1] => Array
(
[id] => 5
[name] => Games
[emoji] => 🎾
[parent_id] => 3
[children] => Array
(
)
)
)
)
)
)
)
And the expected result should be:
0] => Array
(
[id] => 1
[name] => Rusty Corp.
[emoji] => 🐕
[parent_id] =>
)
[1] => Array
(
[id] => 2
[name] => Food
[emoji] => 🥩
[parent_id] => 1
)
[2] => Array
(
[id] => 3
[name] => Canine Therapy
[emoji] => 😌
[parent_id] => 1
)
[3] => Array
(
[id] => 4
[name] => Massages
[emoji] => 💆
[parent_id] => 3
)
[4] => Array
(
[id] => 5
[name] => Games
[emoji] => 🎾
[parent_id] => 3
)
I tried different approaches like array_merge or custom flattening function but can't nail with the expected results, any suggestions?
Edit:
This is my flatten function:
private function flatten_array( array $array ) {
$return = array();
array_walk_recursive(
$array,
function( $a ) use ( &$return ) {
$return[] = $a;
}
);
return $return;
}
Here is a recursive function that will flatten the array, it will not take into account the null value of parent_id on the root element. Also the flattened array will start with the most nested elements at the start of the array and root element at the end.
function flatten_array($array, $flattened = []) {
$current = [];
foreach ($array as $key => $value) {
if (is_array($value))
$flattened = array_merge($flattened, flatten_array($value));
else
$current[$key] = $value;
}
$flattened[] = $current;
return array_filter($flattened);
}

Php creating associative array from another array

I am using an array that I get from a database and I would like to create an associative array from that one.
Here is the code I am using:
print_r($data_sites);
// Format for easy use
$data_sites_formatted = array();
foreach ($data_sites as $key => $row) {
if (empty($data_formatted[$row->project_loe_id])) {
$data_sites_formatted[$row->project_loe_id] = array();
}
$data_sites_formatted[$row->project_loe_id][$row->name] = array();
$data_sites_formatted[$row->project_loe_id][$row->name]['id'] = $row->id;
$data_sites_formatted[$row->project_loe_id][$row->name]['quantity'] = $row->quantity;
$data_sites_formatted[$row->project_loe_id][$row->name]['loe_per_quantity'] = $row->loe_per_quantity;
}
print_r($data_sites_formatted);
Here is the information I receive from the database:
Illuminate\Support\CollectionObject ( [items:protected] => Array (
[0] => stdClass Object ( [id] => 1 [project_loe_id] => 1 [name] => site [quantity] => 20 [loe_per_quantity] => 1 )
[1] => stdClass Object ( [id] => 2 [project_loe_id] => 1 [name] => switches [quantity] => 5 [loe_per_quantity] => 3 )
[2] => stdClass Object ( [id] => 3 [project_loe_id] => 2 [name] => site [quantity] => 20 [loe_per_quantity] => 1 )
[3] => stdClass Object ( [id] => 4 [project_loe_id] => 2 [name] => ap [quantity] => 5 [loe_per_quantity] => 3 )
[4] => stdClass Object ( [id] => 5 [project_loe_id] => 2 [name] => wireless [quantity] => 5 [loe_per_quantity] => 3 ) ) )
And when I do the transformation, here is the result:
Array (
[1] => Array ( [switches] => Array ( [id] => 2 [quantity] => 5 [loe_per_quantity] => 3 ) )
[2] => Array ( [wireless] => Array ( [id] => 5 [quantity] => 5 [loe_per_quantity] => 3 ) ) )
I lost 3 lines and I really have no idea why. I can see when I look into details step by step that it deletes some lines from 1 iteration to the next:
Iteration:0
Array (
[1] => Array ( [site] => Array ( [id] => 1 [quantity] => 20 [loe_per_quantity] => 1 ) ) )
Iteration: 1
Array (
[1] => Array ( [switches] => Array ( [id] => 2 [quantity] => 5 [loe_per_quantity] => 3 ) ) )
Iteration: 2
Array (
[1] => Array ( [switches] => Array ( [id] => 2 [quantity] => 5 [loe_per_quantity] => 3 ) )
[2] => Array ( [site] => Array ( [id] => 3 [quantity] => 20 [loe_per_quantity] => 1 ) ) )
Iteration: 3
Array (
[1] => Array ( [switches] => Array ( [id] => 2 [quantity] => 5 [loe_per_quantity] => 3 ) )
[2] => Array ( [ap] => Array ( [id] => 4 [quantity] => 5 [loe_per_quantity] => 3 ) ) )
Iteration: 4
Array (
[1] => Array ( [switches] => Array ( [id] => 2 [quantity] => 5 [loe_per_quantity] => 3 ) )
[2] => Array ( [wireless] => Array ( [id] => 5 [quantity] => 5 [loe_per_quantity] => 3 ) ) )
You can see from iteration 0 to iteration 1, it deleted the line from iteration 0 and in iteration 1 I should have 2 lines.
You have a typo here:
if (empty($data_formatted[$row->project_loe_id])) {
$data_sites_formatted[$row->project_loe_id] = array();
}
$data_formatted is never defined (you meant to write $data_sites_formatted) so empty($data_formatted[$row->project_loe_id]) is always true, and always runs the next line, replacing anything previously added to $data_sites_formatted[$row->project_loe_id] with an empty array. So all you end up with is the last item to be added in each group.

Joining two multidimensional arrays

I have two arrays each coming from different DB queries, I can't join them in DB so I have to join them using php.
The first:
Array
(
[0] => Array
(
[id] => 23
[host_id] => 5
[pos_id] => 2
[status] => 1
)
[1] => Array
(
[id] => 25
[host_id] => 5
[pos_id] => 1
[status] => 1
)
[2] => Array
(
[id] => 24
[host_id] => 5
[pos_id] => 2
[status] => 1
)
)
And I wanna join it with this array on pos_id and id
Array
(
[0] => Array
(
[id] => 1
[name] => Front
)
[1] => Array
(
[id] => 2
[name] => Back
)
)
so that, the result is:
Array
(
[0] => Array
(
[id] => 23
[host_id] => 5
[pos_id] => 2
[name] => Back
[status] => 1
)
[1] => Array
(
[id] => 25
[host_id] => 5
[pos_id] => 1
[name] => Front
[status] => 1
)
[2] => Array
(
[id] => 24
[host_id] => 5
[pos_id] => 2
[name] => Back
[status] => 1
)
)
The code I have uses an inner loop, matches the value and pushes into array:
foreach($events as &$event) {
foreach($positions as $position) {
if($player[pos_id] == $position[id]){
array_push($event,"name",$position[name]);
}
}
}

PHP add arrays to an array on a specific element

I am trying to merge 2 arrays a single array on a multidimensional array where a given key-value = a value
the first array looks like this:
Array
(
[0] => Array
(
[id] => 4
[subcategories] => Array
(
[0] => Array
(
[id] => 5
[category_order] => 0
[parent_id] => 4
[name] => Audio Equipment
)
[1] => Array
(
[id] => 6
[category_order] => 0
[parent_id] => 4
[name] => Home Entertainment
)
[2] => Array
(
[id] => 7
[category_order] => 0
[parent_id] => 4
[name] => Photography
)
[3] => Array
(
[id] => 8
[category_order] => 0
[parent_id] => 4
[name] => Portable Audio
)
[4] => Array
(
[id] => 9
[category_order] => 0
[parent_id] => 4
[name] => Televisions
)
)
)
)
and the second like this:
Array
(
[0] => Array
(
[id] => 10
[parent_id] => 5
[name] => Amplifiers & Receivers
)
[1] => Array
(
[id] => 11
[parent_id] => 5
[name] => Audio Systems
)
[2] => Array
(
[id] => 12
[parent_id] => 5
[name] => Cassette Decks
)
[3] => Array
(
[id] => 13
[parent_id] => 5
[name] => CD Players
)
[4] => Array
(
[id] => 14
[parent_id] => 5
[name] => Radios
)
[5] => Array
(
[id] => 15
[parent_id] => 5
[name] => HiFi Speakers
)
)
What I want to do is add each of the second arrays to a sub array of the first multidimensional array where the parent_id of the second array = the id of the subcategories array of the first array so it will look like this:
array
(
[0]=> Array
(
[id] => 4
[subcategories] => Array
(
[0] => Array
(
[id] => 5
[category_order] => 0
[parent_id] => 4
[name] => Audio Equipment
[subsubcategories] = array
(
[id] => 10
[parent_id] => 5
[name] => Amplifiers & Receivers
)
)
Something like this should work just rename the array names because you didn't provide them. But I think you'll get the idea :) Mainly you loop through all subcategories with foreach loop or another you'll get the parent id and can access the main array with that parent id and save the sub categories info in there.
foreach( $sub_array as $item ) {
$main_array[ category_id ][ $item[ 'parent_id' ] ][ 'subsubcategories' ] = $item;
}

Children nodes moved to the root level on an hierarchy array

I have the following array on a hierarchy structure - It's basically an array with categories and its children under the 'child' key:
Array
(
[category_id] => 1
[parent_id] => 0
[name] => Commercial
[child] => Array
(
[0] => Array
(
[category_id] => 48
[parent_id] => 1
[name] => lights
[child] => Array
(
)
)
[1] => Array
(
[category_id] => 12
[parent_id] => 1
[name] => beacons
[child] => Array
(
[0] => Array
(
[category_id] => 91
[parent_id] => 12
[name] => blue beacons
[child] => Array
(
)
)
)
)
)
)
What I am trying to do is write a recursive function to reorganize this array as an ONE LEVEL array only. Instead of having its children inside the 'child' key, I want it to be part of the array root level. Like this:
[0] => Array
(
[category_id] => 1
[parent_id] => 0
[name] => Commercial
)
[1] => Array
(
[category_id] => 48
[parent_id] => 1
[name] => lights
)
[2] => Array
(
[category_id] => 12
[parent_id] => 1
[name] => beacons
)
[3] => Array
(
[category_id] => 91
[parent_id] => 12
[name] => blue beacons
)
Any ideas?
Thanks!
The following recursive function should serve your purpose:
function one_level_array($arr){
$ret = array();
$ret[] = array_diff_key($arr, array("child" => ""));
if(array_key_exists("child", $arr)){
foreach($arr["child"] as $child){
$ret = array_merge($ret, one_level_array($child));
}
}
return $ret;
}
DEMO

Categories