PHP Recursive Function to output select - php

I must have blocked out something, I know the answer is simple but for the life of my I cant get any clear answers from Google.
I have this array:
Array
(
[0] => Array
(
[id] => 1
[name] => Paint
[parent_id] => 0
[sub] => Array
(
[0] => Array
(
[id] => 4
[name] => Dulux
[parent_id] => 1
[sub] => Array
(
[0] => Array
(
[id] => 6
[name] => Roof Cover
[parent_id] => 4
[sub] => Array
(
)
)
)
)
[1] => Array
(
[id] => 5
[name] => Plascon
[parent_id] => 1
[sub] => Array
(
)
)
)
)
[1] => Array
(
[id] => 2
[name] => Electrical
[parent_id] => 0
[sub] => Array
(
)
)
[2] => Array
(
[id] => 3
[name] => Plumbing
[parent_id] => 0
[sub] => Array
(
)
)
)
and want to output a select, with option groups. I know this is a 101 PHP thing but been working on this for to long now to figure it out. Any help would be appreciated.

Here's a dirt simple recursive function:
function output_option($arr) {
foreach ($arr as $item) {
if ($item['sub']) {
echo '<optgroup label="', $item['name'], '">';
output_option($arr['sub']);
echo '</optgroup>';
} else {
echo '<option id="', $arr['name'], '">', $arr['name'], '</option>';
}
}
}
Feel free to modify/change it for your needs, but it should be fairly self explanatory.

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);
}

Shift Recursive nested child array to parent array 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));

Get tree comments

Can't get normal tree of comments from database:
Function in model to get data (I use Codeigniter)
public function get_test()
{
$query = $this->db->get('test');
$dataset = $query->result_array();
foreach($dataset as &$row) {
if (!$row['parent_id']) {
$tree[$row['id']] = &$row;
} else {
$tree[$row['parent_id']]['children'][$row['id']] = &$row;
}
}
return $tree;
}
<? echo '<pre>';
print_r($test);
echo '</pre>'; ?>
And this is what I get:
Array
(
[1] => Array
(
[id] => 1
[parent_id] => 0
[name] => Маша
[comment] => Привет всем
[children] => Array
(
[2] => Array
(
[id] => 2
[parent_id] => 1
[name] => Саша
[comment] => И тебе првиет
)
)
)
[3] => Array
(
[id] => 3
[parent_id] => 0
[name] => Даша
[comment] => Ауау
[children] => Array
(
[4] => Array
(
[id] => 4
[parent_id] => 3
[name] => Паша
[comment] => Читай
)
)
)
[2] => Array
(
[children] => Array
(
[5] => Array
(
[id] => 5
[parent_id] => 2
[name] => Петя
[comment] => Еще привет
)
)
)
)
The last array It must be a response to a comment in the first array....What is the problem? I can't find a mistake.
Check again your database maybe by using phpmyadmin because as i saw from the printed array the comment with [id] => 5 has [parent_id] => 2. If you want to display it as child of the comment with [id] => 1 you have to give him the [parent_id] => 1

add data of an index to another index of same array in php

hello I using laravel and magento DB to get data, I want to make tree like structure of following data. Initially when I got data is like this.
Array
(
[parent] => Array
(
[0] => Array
(
[entity_id] => 5740
[name] => Sports
[parent_id] => 5739
)
[1] => Array
(
[entity_id] => 6057
[name] => Football
[parent_id] => 5740
)
[2] => Array
(
[entity_id] => 6058
[name] => American
[parent_id] => 6057
)
)
)
and I want the above data in following format to use in my application.
Array
(
[parent] => Array
(
[0] => Array
(
[entity_id] => 5740
[name] => Sports
[parent_id] => 5739
[child] => Array
(
[entity_id] => 6057
[name] => Football
[parent_id] => 5740
[child]=> Array
(
[entity_id] => 6058
[name] => American
[parent_id] => 6057
)
)
)
)
)
can anyone please help me in this.
Solution handling unordered hierarchies
function hierarchize($data){
$parentLess = [];
$map = [];
foreach($data['parent'] as &$entity){
$id = $entity['entity_id'];
$parentId = $entity['parent_id'];
$map[$id] = &$entity;
if(isset($map[$parentId])){
$map[$parentId]['child'][] = &$entity;
}else{
$parentLess[$parentId][] = &$entity;
}
if(isset($parentLess[$id])){
$entity['child'] = &$parentLess[$id];
unset($parentLess[$id]);
}
}
return $parentLess;
}
https://eval.in/145508

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