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
Related
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>'
I have the following array structure:
[parents] => Array
(
[0] => Array
(
[id] => 1
[user_id] => 1
[created] => 2014-11-09 13:47:37
[content] => This is a test discussion
[status] => 1
[parent] => 0
[project_id] => 1
)
[1] => Array
(
[id] => 4
[user_id] => 1
[created] => 2014-11-09 13:52:02
[content] => 456789
[status] => 1
[parent] => 0
[project_id] => 1
)
)
[children] => Array
(
[0] => Array
(
[id] => 2
[user_id] => 1
[created] => 2014-11-09 13:47:53
[content] => This is a test reply....
[status] => 1
[parent] => 1
[project_id] => 1
)
[1] => Array
(
[id] => 3
[user_id] => 1
[created] => 2014-11-09 13:48:13
[content] => This is a test reply....!!!
[status] => 1
[parent] => 1
[project_id] => 1
)
[2] => Array
(
[id] => 5
[user_id] => 1
[created] => 2014-11-09 13:52:17
[content] => 8765432
[status] => 1
[parent] => 4
[project_id] => 1
)
)
I would like to merge them into a parent/child relationship so it looks like follows:
[parents] => Array
(
[0] => Array
(
[id] => 1
[user_id] => 1
[created] => 2014-11-09 13:47:37
[content] => This is a test discussion
[status] => 1
[parent] => 0
[project_id] => 1
[children] => Array
(
[0] => Array
(
[id] => 2
[user_id] => 1
[created] => 2014-11-09 13:47:53
[content] => This is a test reply....
[status] => 1
[parent] => 1
[project_id] => 1
)
[1] => Array
(
[id] => 3
[user_id] => 1
[created] => 2014-11-09 13:48:13
[content] => This is a test reply....!!!
[status] => 1
[parent] => 1
[project_id] => 1
)
)
)
)
How could I go about doing that with PHP?
Assuming that all ids are unique in your parents array, you can do this:
// build a new array using parent's ID values as the key,
// to simplify searching for parent IDs.
foreach ($parents as $key => $value){
$merged[$value['id']] = $value;
}
foreach ($children as $child){
$parentID = $child['parent'];
if (array_key_exists( $parentID, $merged )) {
// add the child array to its parent's ['children'] value
$merged[$parentID]['children'][] = $child;
}
}
In the resulting array $merged, the key of each parent item will be set to its id, and all children will be nested under their corresponding parents.
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.
I've got an array with data from a MySQL table in nested set model I'd like to get sorted, not only alphabetical but also with the child nodes directly after the parent node.
Example - array to be sorted (before the sorting):
Array
(
[0] => Array
(
[id] => 1
[name] => Kompetenser
[parent] => 0
[depth] => 0
)
[1] => Array
(
[id] => 2
[name] => Administration
[parent] => 1
[depth] => 1
)
[2] => Array
(
[id] => 11
[name] => Organisation
[parent] => 2
[depth] => 2
)
[3] => Array
(
[id] => 4
[name] => Arbetsledning
[parent] => 2
[depth] => 2
)
[4] => Array
(
[id] => 17
[name] => Planering
[parent] => 2
[depth] => 2
)
[5] => Array
(
[id] => 9
[name] => Hantverke
[parent] => 1
[depth] => 1
)
[6] => Array
(
[id] => 10
[name] => Snickeri
[parent] => 9
[depth] => 2
)
[7] => Array
(
[id] => 12
[name] => Språk
[parent] => 1
[depth] => 1
)
[8] => Array
(
[id] => 13
[name] => Tolk
[parent] => 12
[depth] => 2
)
[9] => Array
(
[id] => 15
[name] => Arabiska
[parent] => 13
[depth] => 3
)
[10] => Array
(
[id] => 14
[name] => Persiska
[parent] => 13
[depth] => 3
)
[11] => Array
(
[id] => 16
[name] => Polska
[parent] => 13
[depth] => 3
)
[12] => Array
(
[id] => 18
[name] => Apotekare
[parent] => 1
[depth] => 1
)
[13] => Array
(
[id] => 19
[name] => Dotkorand
[parent] => 1
[depth] => 1
)
[14] => Array
(
[id] => 21
[name] => Atomfysik
[parent] => 19
[depth] => 2
)
[15] => Array
(
[id] => 20
[name] => Fysik
[parent] => 19
[depth] => 2
)
[16] => Array
(
[id] => 22
[name] => Ekonom
[parent] => 1
[depth] => 1
)
[17] => Array
(
[id] => 23
[name] => Industriell ekonomi
[parent] => 22
[depth] => 2
)
[18] => Array
(
[id] => 24
[name] => Filosofi
[parent] => 1
[depth] => 1
)
)
I want the array this way (after the sorting):
Array
(
[0] => Array
(
[id] => 1
[name] => Kompetenser
[parent] => 0
[depth] => 0
)
[1] => Array
(
[id] => 2
[name] => Administration
[parent] => 1
[depth] => 1
)
[3] => Array
(
[id] => 4
[name] => Arbetsledning
[parent] => 2
[depth] => 2
)
[2] => Array
(
[id] => 11
[name] => Organisation
[parent] => 2
[depth] => 2
)
[4] => Array
(
[id] => 17
[name] => Planering
[parent] => 2
[depth] => 2
)
[12] => Array
(
[id] => 18
[name] => Apotekare
[parent] => 1
[depth] => 1
)
[13] => Array
(
[id] => 19
[name] => Dotkorand
[parent] => 1
[depth] => 1
)
[14] => Array
(
[id] => 21
[name] => Atomfysik
[parent] => 19
[depth] => 2
)
[15] => Array
(
[id] => 20
[name] => Fysik
[parent] => 19
[depth] => 2
)
[16] => Array
(
[id] => 22
[name] => Ekonom
[parent] => 1
[depth] => 1
)
[17] => Array
(
[id] => 23
[name] => Industriell ekonomi
[parent] => 22
[depth] => 2
)
[18] => Array
(
[id] => 24
[name] => Filosofi
[parent] => 1
[depth] => 1
)
[5] => Array
(
[id] => 9
[name] => Hantverke
[parent] => 1
[depth] => 1
)
[6] => Array
(
[id] => 10
[name] => Snickeri
[parent] => 9
[depth] => 2
)
[7] => Array
(
[id] => 12
[name] => Språk
[parent] => 1
[depth] => 1
)
[8] => Array
(
[id] => 13
[name] => Tolk
[parent] => 12
[depth] => 2
)
[9] => Array
(
[id] => 15
[name] => Arabiska
[parent] => 13
[depth] => 3
)
[10] => Array
(
[id] => 14
[name] => Persiska
[parent] => 13
[depth] => 3
)
[11] => Array
(
[id] => 16
[name] => Polska
[parent] => 13
[depth] => 3
)
)
As you might see, I want all posts with parent 2 directly after the post with id 2, and so on.
Any help would be highly appreciated.
Thank you in advance.
Don't do this in PHP!
The MySQL server is specificly designed to query AND sort data, read up on the MySQL "ORDER BY" syntax. Doing this on the MySQL server will save run-time, CPU Load and Memory Consumption.
Use php's uasort() function to define your own comparison function.
But using MySQL's sorting capabilities would be more appropriate, if it's possible in your case.
You want to sort it like it is in the DB, multilayered. I don't think uasort can help with this problem because you want to attach the children to the parent.
foreach ($arr as &$val) {
$arr2[$val['id']] = &$val;
}
ksort($arr2);
foreach ($arr2 as $id => &$val) {
$parent = $val['parent'];
if ($parent == 0) {
continue;
}
$arr2[$parent]['children'][$id] = &$val;
}
function flattenArrayByChildren($arr) {
foreach ($arr as $id => $val) {
if (isset($val['children'])) {
$temp = flattenArrayByChildren($val['children']);
unset($val['children']);
$out[$id] = $val;
$out = $out + $temp;
} else {
$out[$id] = $val;
}
}
return $out;
}
$arr2 = array(1 => $arr2[1]);
$out = flattenArrayByChildren($arr2);
var_dump($out);
If you absolutely want to save the key, you can just add that to the $val in the first foreach, and retrieve it in the recursive function flattenArrayByChildren and use as key.
Problem solved - I made two simple functions. I hope other people could have use of this as well:
class data_comp
{
var $fetched_tree = array();
function tree_fetch($parent = 0)
{
$query = 'SELECT node.id, node.name, node.parent, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.name';
$result = mysql_query($query) or die(mysql_error());
$tree = array();
while($data = mysql_fetch_assoc($result))
{
$tree[$data['parent']][$data['id']] = array('name' => $data['name'], 'depth' => $data['depth']);
}
$this->tree_print($tree, $parent);
}
function tree_print($tree, $parent)
{
foreach($tree[$parent] as $id => $value)
{
$this->fetched_tree[] = array('id' => $id, 'name' => $value['name'], 'depth' => $value['depth']);
if(isset($tree[$id]) && is_array($tree[$id]))
{
$this->tree_print($tree, $id);
}
}
}
}
Thank you for your time. Any improvements are more than welcome.