Create a separate auxiliary array based on the array key
I need to split one array into sub arrays based on the number of times >
that appears in the array key so that I can tell who is the parent category and who is not. Please note that there is no limit to the number of possible nested parents.
Also, if a child of the same name exists, it is considered unique if it has a different parent.
The structure of the original array looks like this:
array (
'Test Parent 2>Test Child>Test Sub Child' =>
array (
'content_id_4' => NULL,
),
'Test Parent 3' =>
array (
'content_id_4' => NULL,
'content_id_5' => NULL,
),
'Test Parent>Test Child>Test Sub Child' =>
array (
'content_id_3' => NULL,
),
'Test Parent 2 with No Kids' =>
array (
'content_id_3' => NULL,
),
'Collections>Sports' =>
array (
'content_id_2' => NULL,
'content_id_22' => NULL,
),
'Collections' =>
array (
'content_id_2' => NULL,
'content_id_22' => NULL,
'content_id_6' => NULL,
),
'Collections>Charity' =>
array (
'content_id_6' => NULL,
),
)
The above example Test Parent>Test Child>Test Sub Child
means that there is a parent category Test Parent
that has a child Test Child
. Test Child
is also a parent and has a child Test Sub Child
that has no children.
Required output required:
array (
'Collections' =>
array (
'Sports' => NULL,
'Charity' => NULL,
),
'Test Parent' =>
array (
'Test Child' =>
array (
'Test Sub Child' => NULL,
),
),
'Test Parent 2 with No kids' => NULL,
'Study' =>
array (
'Study Groups' => NULL,
),
)
I tried to find a solution, but can't get the syntax right to create an additional array with child children.
I don't need to have my example refactored. I'm just looking for the best solution that works.
My example code
$category_structure = array();
foreach($event_categories as $main_cat => $content_ids) {
$this_category_list = explode('>', $main_cat);
$this_cat = array();
$this_parent = array_shift($this_category_list);
foreach($this_category_list as $cat) {
$this_cat[$this_parent][$cat] = null;
}
$category_structure = array_merge_recursive($this_cat, $category_structure);
}
source to share
This should work for you, making sure there are no null indexed items as a result. Which comes from array_merge_recursive
, I think, combining the null element with those that have an associative key.
It's not as elegant as P0rnflake's solution, but I'm sure you get the idea.
$collect = array();
$result = array();
$last = "";
foreach($event_categories as $main_cat => $content_ids) {
if (strpos($last, $main_cat) === false) {
array_push($collect, explode('>', $main_cat));
}
$last = $main_cat;
}
array_walk($collect, function($value) use (&$result) {
$out = array();
$cur = &$out;
foreach ($value as $array) {
if (count($value) !== 1) {
$cur[$array] = array();
} else {
$cur[$array] = null;
}
$cur = &$cur[$array];
}
$cur = null;
$result = array_merge_recursive($result, $out);
});
var_dump($result);
source to share
This solution should work for php> = 5.3.0 ($ yourArray is the input array):
// anonymous recursive function which merges a flat numeric array
// into a hierarchy, f.e. array('parent','child','grandchild')
// will be built to a hierarchical array
$treeBuilder = function($numArray) use (&$treeBuilder) {
if(isset($numArray[1])) {
//recursive merge needed, there are still entries left
return array(
$numArray[0] => $treeBuilder(array_slice($numArray, 1))
);
}
//end is reached
return array(
$numArray[0] => null
);
};
$result = array();
foreach (array_keys($yourArray) as $key) {
// loop through exploded keys and merge results
$hierarchy = explode('>', $key);
$result = array_merge_recursive($result, $treeBuilder($hierarchy));
}
var_dump($result);
source to share