this is my array
Array
(
[category_id] => 4
[parent_id] => 3
[name] => Default Category
[is_active] => 1
[position] => 4
[level] => 2
[children] => Array
(
[0] => Array
(
[category_id] => 122
[parent_id] => 4
[name] => Root
[is_active] => 1
[position] => 1
[level] => 3
[children] => Array
(
[0] => Array
(
[category_id] => 123
[parent_id] => 122
[name] => Clothing
[is_active] => 1
[position] => 1
[level] => 4
[children] => Array
(
[0] => Array
(
[category_id] => 124
[parent_id] => 123
[name] => Men Clothing
[is_active] => 1
[position] => 1
[level] => 5
[children] => Array
(
[0] => Array
(
[category_id] => 125
[parent_id] => 124
[name] => Polos & Tees
[is_active] => 1
[position] => 1
[level] => 6
[children] => Array
(
)
)
)
)
)
)
[1] => Array
(
[category_id] => 126
[parent_id] => 122
[name] => Fashion
[is_active] => 1
[position] => 2
[level] => 4
[children] => Array
(
[0] => Array
(
[category_id] => 127
[parent_id] => 126
[name] => Footwear
[is_active] => 1
[position] => 1
[level] => 5
[children] => Array
(
[0] => Array
(
[category_id] => 128
[parent_id] => 127
[name] => Women
[is_active] => 1
[position] => 1
[level] => 6
[children] => Array
(
[0] => Array
(
[category_id] => 129
[parent_id] => 128
[name] => Flats
[is_active] => 1
[position] => 1
[level] => 7
[children] => Array
(
)
)
)
)
)
)
)
)
)
)
)
)
and
what I want to do is that :
write a function
foo($find,$array){
//do some coding to search in the array
return $category_id;//category id of the coresponding matched name in array
}
for example :
foo("Clothing",$array); will return 18
foo("Men Clothing",$array) will return 19
and so on
You can use recursion. An example here..
function getId($arr, $val){
if(is_array($arr)){
if(isset($arr['name']) && trim($arr['name']) == trim($val)){
return isset($arr['category_id']) ? $arr['category_id'] : 'Not found';
}
foreach($arr as $values){
if(is_array($values)){
return getId($values, $val);
}
}
}
}
$val = getId($arr, 'Polos & Tees');
echo $val; //output 20
This is a solution with a recursion:
function foo($find, $array) {
if( $array['name'] == $find ) {
return $array['category_id'];
}
if( empty($array['children']) ) {
return null;
}
foreach($array['children'] as $child) {
$result = foo($find, $child);
if( $result !== null ) {
return $result;
}
}
return null;
}
echo foo('Default Category', $array), "\n"; // 4
echo foo('Root', $array), "\n"; // 122
echo foo('Clothing', $array), "\n"; // 123
echo foo('Men Clothing', $array), "\n"; // 124
echo foo('Polos & Tees', $array), "\n"; // 125
echo foo('Fashion', $array), "\n"; // 126
echo foo('Footwear', $array), "\n"; // 127
echo foo('Women', $array), "\n"; // 128
echo foo('Flats', $array), "\n"; // 129
Related
I'm trying to get a multidimensional array comparing the [id] values with the [parent_id] values from an array like this:
Array
(
[0] => Array
(
[id] => 101
[title] => parent_101
[parent_id] => 0
[level] => 1
)
[1] => Array
(
[id] => 118
[title] => parent_118
[parent_id] => 0
[level] => 1
)
[2] => Array
(
[id] => 119
[title] => child_119
[parent_id] => 118
[level] => 2
)
[4] => Array
(
[id] => 173
[title] => subchild_173
[parent_id] => 119
[level] => 3
)
[5] => Array
(
[id] => 120
[title] => child_120
[parent_id] => 118
[level] => 2
)
[6] => Array
(
[id] => 145
[title] => deeperchild_145
[parent_id] => 173
[level] => 4
)
)
The result should be a new array like this:
Array
(
[0] => Array
(
[title] => parent_101
[id] => 101
[parent_id] => 1
[level] => 1
[childrens] => Array
(
)
)
[1] => Array
(
[id] => 118
[title] => parent_118
[parent_id] => 1
[level] => 1
[childrens] => Array
(
[0] => Array
(
[id] => 119
[title] => child_119
[parent_id] => 118
[level] => 2
[deeper] => Array
(
[0] => Array
(
[id] => 173
[title] => subchild_173
[parent_id] => 119
[level] => 3
[deeperchild] => Array
(
[id] => 145
[title] => deeperchild_145
[parent_id] => 173
[level] => 4
)
)
)
)
[1] => Array
(
[id] => 120
[title] => parent_120
[parent_id] => 118
[level] => 2
[deeper] => Array
(
)
)
)
)
)
so far I come up with this code but I'm stuck at the 3rd level deeper and I was wondering if there is a better way to do that.
> $parentsitms = array(); $deeperArr = array(); $childsArr = array();
> $childparent = array(); $menu = array();
>
> foreach ($list as $items) {
>
> if($items->level==='1'):
> $idparent = $items->id;
> $parents = $items->title;
> $parentsitms[] = ['id'=>$items->id,'title'=>$items->title,'parent_id'=>$items->parent_id,'level'=>$items->level];
>
> endif;
>
> }
> foreach ($parentsitms as $menuitm) {
> $parents = $menuitm;
>
> foreach($list as $chd){
>
> if($menuitm['id'] === $chd->parent_id):
> $childparent = $chd->id;
> $childsItms = ['id'=>$chd->id,'title'=>$chd->title,'parent_id'=>$chd->parent_id,'level'=>$chd->level];
> $childsArr[] = [array_merge($childsItms,array('deeper'=>array()))];
> endif;
>
> if($childparent === $chd->parent_id):
> $array = ['title'=>$chd->title,'id'=>$chd->id,'parent_id'=>$chd->parent_id,'level'=>$chd->level];
> $deeperArr[] = ['id'=>$chd->id,'title'=>$chd->title,'parent_id'=>$chd->parent_id,'level'=>$chd->level];
> $childsArr = [array_merge($childsItms,array('deeper'=>$deeperArr))];
> endif;
>
> ######## can't get the 4th level deeper ######
>
>
> }
>
> $menu[] = array_merge($parents,array('childrens'=>$childsArr));
> }
>
> echo '<pre>'; print_r($menu);
Any help is very appreciated.
This code uses a non-recursive method which is a more common method of solving this type of problem. I prefer this method as it makes just one pass through the data and can be easier to follow through (IMHO).
I've added comments to the code as it's easier to describe with the code. The only thing I would say is that this always uses children as the name of the child elements and not the way you do this at the moment...
// Order array so that they are in order of level
usort($list, function ( $a, $b ) { return $a['level'] <=> $b['level']; });
// Create start point with all of the items indexed by their ID
$output = array_column($list, null, "id");
// Work in reverse order
foreach ( array_reverse(array_column($list, "id")) as $id ) {
$parent = $output[$id]['parent_id'];
// If there is a parent to work with
if ( $parent != 0 ) {
// Ensure that the add point is there
if ( !isset($output[$parent]['children']) ) {
$output[$parent]['children'] = [];
}
// Prepend the new item to the list (do this as the items
// are added in reverse oder)
array_unshift($output[$parent]['children'], $output[$id]);
// Remove the old node from the base list
unset($output[$id]);
}
}
$output = array_values($output);
print_r($output);
gives...
Array
(
[0] => Array
(
[id] => 101
[title] => parent_101
[parent_id] => 0
[level] => 1
)
[1] => Array
(
[id] => 118
[title] => parent_118
[parent_id] => 0
[level] => 1
[children] => Array
(
[0] => Array
(
[id] => 119
[title] => child_119
[parent_id] => 118
[level] => 2
[children] => Array
(
[0] => Array
(
[id] => 173
[title] => subchild_173
[parent_id] => 119
[level] => 3
[children] => Array
(
[0] => Array
(
[id] => 145
[title] => deeperchild_145
[parent_id] => 173
[level] => 4
)
)
)
)
)
[1] => Array
(
[id] => 120
[title] => child_120
[parent_id] => 118
[level] => 2
)
)
)
)
i have a big problem to u resolve, it's killing me.
See a Array response:
Array (
[category_id] => 1
[parent_id] => 0
[name] => Root Catalog
[is_active] =>
[position] => 0
[level] => 0
[children] => Array
(
[0] => Array
(
[category_id] => 2
[parent_id] => 1
[name] => AutomaBrasil
[is_active] => 1
[position] => 1
[level] => 1
[children] => Array
(
[0] => Array
(
[category_id] => 3
[parent_id] => 2
[name] => Automação
[is_active] => 1
[position] => 1
[level] => 2
[children] => Array
(
)
)
[1] => Array
(
[category_id] => 4
[parent_id] => 2
[name] => Balança
[is_active] => 1
[position] => 2
[level] => 2
[children] => Array
(
)
)
[2] => Array
(
[category_id] => 5
[parent_id] => 2
[name] => Caixa Registradora
[is_active] => 1
[position] => 3
[level] => 2
[children] => Array
(
)
)
[3] => Array
(
[category_id] => 6
[parent_id] => 2
[name] => Gaveta de Dinheiro
[is_active] => 1
[position] => 4
[level] => 2
[children] => Array
(
[0] => Array
(
[category_id] => 10
[parent_id] => 6
[name] => Acessórios
[is_active] => 1
[position] => 1
[level] => 3
[children] => Array
(
)
)
[1] => Array
(
[category_id] => 12
[parent_id] => 6
[name] => Gaveta de Dinheiro Automática
[is_active] => 1
[position] => 2
[level] => 3
[children] => Array
(
)
)
)
)
[4] => Array
(
[category_id] => 7
[parent_id] => 2
[name] => Impressora
[is_active] => 1
[position] => 5
[level] => 2
[children] => Array
(
)
)
)
)
))
Until then beauty, but when i try the "foreach", it returns me this:
1
0
Root Catalog
0
0
Array
I need it to print the complete tree inside the tags <ul> <li>.
I'm use recursive foreach:
public function createTree($lists) {
echo '<ul>';
foreach ($lists as $list) {
echo '<li>';
echo $list['name'] . '';
echo '</li>';
if (is_array($list['children'])) {
$this->createTree($list['children']);
}
}
echo '</ul>';
}
U can help me? Tks!
You could try to wrap the output children array into li:
Wrap the $this->createTree($list['children'] into echo '<li>'; $this->createTree($list['children']); echo '</li>'
how to make tree with the following multidimensional array?
the child items have a non-zero parentID
Array
(
[0] => Array
(
[id] => 6
[title] => zzz
[parentID] => 0
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[1] => Array
(
[0] => Array
(
[id] => 7
[title] => 7
[parentID] => 6
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[1] => Array
(
[0] => Array
(
[id] => 8
[title] => 8
[parentID] => 7
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
)
)
[2] => Array
(
[id] => 1
[title] => تست
[parentID] => 0
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[3] => Array
(
[0] => Array
(
[id] => 4
[title] => 4
[parentID] => 1
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[1] => Array
(
[id] => 5
[title] => 5
[parentID] => 1
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
)
)
if i want to show items by id, i need following result :
6
-7
--8
1
-4
-5
my attempt :
foreach ($array as $category)
{
$dash = str_repeat("-", array_depth($category));
echo $dash . $category['id'];
}
Is that what you want it?
function arrayStack( $array, $dash ){
foreach($array as $value){
if(isset($value['id'])){
echo str_repeat("-", $dash).$value['id'].',';
}else{
$dash++;
arrayStack( $value, $dash );
$dash--;
}
}
}
arrayStack( $myArray, 0 );
Demo
how to make tree with the following multidimensional array?
the child items have a non-zero parentID
Array
(
[0] => Array
(
[id] => 6
[title] => zzz
[parentID] => 0
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[1] => Array
(
[0] => Array
(
[id] => 7
[title] => 7
[parentID] => 6
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[1] => Array
(
[0] => Array
(
[id] => 8
[title] => 8
[parentID] => 7
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
)
)
[2] => Array
(
[id] => 1
[title] => تست
[parentID] => 0
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[3] => Array
(
[0] => Array
(
[id] => 4
[title] => 4
[parentID] => 1
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
[1] => Array
(
[id] => 5
[title] => 5
[parentID] => 1
[parentName] =>
[section] => articles
[sort] => 0
[level] => 0
)
)
)
if i want to show items by id, i need following result :
6
-7
--8
1
-4
-5
my attempt :
foreach ($array as $category)
{
$dash = str_repeat("-", array_depth($category));
echo $dash . $category['id'];
}
Something along the lines of
function render_node($node, $indent = '') {
$indent .= '-';
echo $indent . $node[0]['id'];
for($i = 1; $i < array_length($node); $i++) {
render_node($node[$i], "$indent-");
}
}
Not tested, but hope you get the idea. There may be an off by one error and some other oddities.
Its generally related to a question in magento ..but i think using core php can also give me a wat i want
Im having a looping array issue here,My aray is like this
Array
(
[0] => Array
(
[category_id] => 2
[parent_id] => 1
[name] => Koffersenkisten
[is_active] => 0
[position] => 1
[level] => 1
[children] => Array
(
[0] => Array
(
[category_id] => 40
[parent_id] => 2
[name] => Muziek
[is_active] => 1
[position] => 1
[level] => 2
[children] => Array
(
[0] => Array
(
[category_id] => 46
[parent_id] => 40
[name] => Gitaar koffer
[is_active] => 1
[position] => 1
[level] => 3
[children] => Array
(
[0] => Array
(
[category_id] => 50
[parent_id] => 46
[name] => Bas gitaar koffer
[is_active] => 1
[position] => 1
[level] => 4
[children] => Array
(
)
)
[1] => Array
(
[category_id] => 51
[parent_id] => 46
[name] => Electrische gitaar koffer
[is_active] => 1
[position] => 2
[level] => 4
[children] => Array
(
)
)
[2] => Array
(
[category_id] => 47
[parent_id] => 46
[name] => Akoestische gitaar koffer
[is_active] => 1
[position] => 3
[level] => 4
[children] => Array
(
)
)
[3] => Array
(
[category_id] => 49
[parent_id] => 46
[name] => Gitaar soft cases
[is_active] => 1
[position] => 4
[level] => 4
[children] => Array
(
)
)
[4] => Array
(
[category_id] => 52
[parent_id] => 46
[name] => Gitaar gig bags
[is_active] => 1
[position] => 5
[level] => 4
[children] => Array
(
)
)
[5] => Array
(
[category_id] => 53
[parent_id] => 46
[name] => Pedalboards
[is_active] => 1
[position] => 6
[level] => 4
[children] => Array
(
)
)
[6] => Array
(
[category_id] => 48
[parent_id] => 46
[name] => Amp Utility Vehicles
[is_active] => 1
[position] => 7
[level] => 4
[children] => Array
(
)
)
)
)
[1] => Array
(
[category_id] => 67
[parent_id] => 40
[name] => Percussie koffer
[is_active] => 1
[position] => 2
[level] => 3
[children] => Array
(
[0] => Array
(
[category_id] => 73
[parent_id] => 67
[name] => Tom koffer
[is_active] => 1
[position] => 1
[level] => 4
[children] => Array
(
)
)
.......
......
>> it goes like this based on the number of categories
How do i get a simple array of the above like this
array('2' => 'Koffersenkisten','40'=> 'Muziek'...........etc); where 2 is the category_id and Koffersenkisten is the name
This function iterates over all items, and recurses when children are found. It passes the output array along at every invocation and appends to it:
function get_cats(array &$output, array $arr)
{
foreach ($arr as $item) {
$output[$item['category_id']] = $item['name'];
if (count($item['children'])) {
get_cats($output, $item['children']);
}
}
}
// start with empty result
$output = array();
get_cats($output, $a);
print_r($output);
This should work. Didn't test it.
$result = array();
function buildArray($array, $stack)
{
foreach($array as $item)
{
$stack[$item['category_id']] = $item['name'];
if(isset($item['children']) && count($item['children']) > 0)
foreach($item['children'] as $child)
buildArray($item['children'], &$stack);
}
}
buildArray($array, &$result);
print_r($result);
Here is a recursive solution (the array should be in $list before, the created array will be in $result after calling the create function):
function create($list, &$result) {
if (is_array($list) && !isset($list['category_id'])) {
foreach ($list as $element) {
create($element, $result);
}
} else {
$result[$list['category_id']] = $list['name'];
create($list['children'], $result);
}
}
create($list, $result);
Also see this example.