Массив переупорядочения PHP для отображения иерархии родительских / идентификационных данных

Как изменить следующий массив

[0] => Array ( [id] => 1 [parent_id] => 0 [name] => Accueil ) [1] => Array ( [id] => 2 [parent_id] => 0 [name] => Exposants ) [2] => Array ( [id] => 3 [parent_id] => 0 [name] => Visiteurs ) [3] => Array ( [id] => 4 [parent_id] => 0 [name] => Medias ) [4] => Array ( [id] => 5 [parent_id] => 0 [name] => Activités ) [5] => Array ( [id] => 6 [parent_id] => 1 [name] => Contact ) [6] => Array ( [id] => 7 [parent_id] => 3 [name] => Partenaires ) [7] => Array ( [id] => 8 [parent_id] => 2 [name] => News ) 

Итак, я придумываю массив, который отражает иерархию, как показано полями id и parent_id? Ключ массива – это поле идентификатора элементов массива – это родители. Внутри этого массива каждый раз есть дочерний массив, у которого есть поле ID в качестве ключа. Образец:

 [1] => Array ( [name] => Accueil [children] => array( [0] => bla, [3] => bla2 ) ) [2] => Array ( [name] => Something [children] => array( [4] => bla3, ) ) 

Solutions Collecting From Web of "Массив переупорядочения PHP для отображения иерархии родительских / идентификационных данных"

Работает на любой глубине и позволяет детям предшествовать родителям:

 <?php $p = array(0 => array()); foreach($nodes as $n) { $pid = $n['parent_id']; $id = $n['id']; if (!isset($p[$pid])) $p[$pid] = array('child' => array()); if (isset($p[$id])) $child = &$p[$id]['child']; else $child = array(); $p[$id] = $n; $p[$id]['child'] = &$child; unset($p[$id]['parent_id']); unset($child); $p[$pid]['child'][] = &$p[$id]; } $nodes = $p['0']['child']; unset($p); ?> с <?php $p = array(0 => array()); foreach($nodes as $n) { $pid = $n['parent_id']; $id = $n['id']; if (!isset($p[$pid])) $p[$pid] = array('child' => array()); if (isset($p[$id])) $child = &$p[$id]['child']; else $child = array(); $p[$id] = $n; $p[$id]['child'] = &$child; unset($p[$id]['parent_id']); unset($child); $p[$pid]['child'][] = &$p[$id]; } $nodes = $p['0']['child']; unset($p); ?> с <?php $p = array(0 => array()); foreach($nodes as $n) { $pid = $n['parent_id']; $id = $n['id']; if (!isset($p[$pid])) $p[$pid] = array('child' => array()); if (isset($p[$id])) $child = &$p[$id]['child']; else $child = array(); $p[$id] = $n; $p[$id]['child'] = &$child; unset($p[$id]['parent_id']); unset($child); $p[$pid]['child'][] = &$p[$id]; } $nodes = $p['0']['child']; unset($p); ?> с <?php $p = array(0 => array()); foreach($nodes as $n) { $pid = $n['parent_id']; $id = $n['id']; if (!isset($p[$pid])) $p[$pid] = array('child' => array()); if (isset($p[$id])) $child = &$p[$id]['child']; else $child = array(); $p[$id] = $n; $p[$id]['child'] = &$child; unset($p[$id]['parent_id']); unset($child); $p[$pid]['child'][] = &$p[$id]; } $nodes = $p['0']['child']; unset($p); ?> 

Используйте var_dump для результата $nodes чтобы увидеть структуру. Это близко к тому, что вы предложили. Основное различие заключается в том, что ключи не являются идентификаторами.

Вы можете сделать это более сухим, но это быстрый и грязный способ справиться с этим. Кроме того, вы можете удалить 6 строк, если вы можете гарантировать, что каждая дочерняя запись имеет действительную родительскую запись и что действительная родительская запись предшествует дочерней записи в исходном массиве.

 $sorted = array(); foreach( $orig_ary as $item ) { if ( $item['parent_id'] === 0 ) { if ( !array_key_exists( $item['id'], $sorted ) ) { $sorted[ $item['id'] ] = array( 'name' => '', 'children' => array() ); } $sorted[ $item['id'] ]['name'] = $item['name']; } else { if ( !array_key_exists( $item['parent_id'], $sorted ) ) { $sorted[ $item['parent_id'] ] = array( 'name' => '', 'children' => array() ); } $sorted[ $item['parent_id'] ]['children'][ $item['id'] ] = $item['name']; } }