2011-12-28 5 views
0

Я даже не знает, как начать формулировку этого вопрос, но в принципе, у меня есть массив, который выглядит следующим образом:PHP - Создание иерархического массива

Array 
(
    [0] =>/
    [1] => /404/ 
    [2] => /abstracts/ 
    [3] => /abstracts/edit/ 
    [4] => /abstracts/review/ 
    [5] => /abstracts/view/ 
    [6] => /admin/ 
    [7] => /admin/ads/ 
    [8] => /admin/ads/clickcounter/ 
    [9] => /admin/ads/delete/ 
    [10] => /admin/ads/edit/ 
    [11] => /admin/ads/list/ 
    [12] => /admin/ads/new/ 
    [13] => /admin/ads/sponsordelete/ 
    [14] => /admin/ads/sponsoredit/ 
    [15] => /admin/ads/sponsornew/ 
    [16] => /admin/ads/stats/ 
    [17] => /admin/boilerplates/ 
    [18] => /admin/boilerplates/deleteboiler/ 
    [19] => /admin/boilerplates/editboiler/ 
    [20] => /admin/boilerplates/newboilerplate/ 
    [21] => /admin/calendar/event/add/ 
    [22] => /admin/calendar/event/copy/ 
) 

И мне нужно, чтобы «уменьшить»/" процесс в массив, который выглядит следующим образом:

Array 
(
    [''] => Array() 
    ['404'] => Array() 
    ['abstracts'] => Array 
        (
          [''] => Array() 
          ['edit'] => Array() 
          ['review'] => Array() 
          ['view'] => Array() 
        ) 
    ['admin'] => Array 
        (
          ['ads'] => Array 
            (
             [''] => Array() 
             ['clickcounter'] => Array() 
             ['delete'] =>Array() 
             ['edit'] => Array() 
            ) 
        ) 
    ..... 
    ..... 
) 

что, если вручную инициализируется будет выглядеть примерно так:

$urlTree = array(''   => array(), 
        '404'  => array(), 
        'abstracts'=> array(''  => array(), 
             'edit' => array(), 
             'review'=> array(), 
             'view' => array()), 
        'admin' => array('ads'=> array(''   => array(), 
                 'clickcounter'=> array(), 
                 'delete'  => array(), 
                 'edit'  => array())) 
); 

Я обычно отклоняюсь от запроса прямо на кусок кода на SO, но есть ли у кого-нибудь какие-либо советы/коды, которые могут пересекать мой массив и преобразовывать его в иерархию?

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

function loadUrlData() 
    { 
    // hold the raw data, /blah/blah/ 
    $urlData = array(); 

    $res = sql::query("SELECT DISTINCT(`url`) FROM `pages` ORDER BY `url` ASC"); 
    while($row = sql::getarray($res)) 
    { 
     $urlData[] = explode('/', substr($row['url'], 1, -1)); 
    } 

    // populated, eventually, with the parent > child data 
    $treeData = array(); 

    // a url 
    foreach($urlData as $k=> $v) 
    { 
     // the url pieces 
     foreach($v as $k2=> $v2) 
     { 

     } 
    } 

    // $treeData eventually 
    return $urlData; 
    } 
+0

Не должны ли все URL-адреса, такие как 404, аннотация и т. Д. Находиться внутри ''? –

ответ

2

Выглядит довольно легко. Вы хотите прокрутить все строки (foreach), разбить их на части (explode), пронести через них (foreach) и классифицировать их.

Поскольку вам не нравится просить кусок кода, я не буду предоставлять никаких данных.

Update
Очень хороший способ решить эту проблему, чтобы ссылаться на $urlTree (используйте &), цикл через каждую часть URL и постоянно обновлять переменную как $currentPosition к текущей части в дереве URL. Поскольку вы используете &, вы можете просто отредактировать массив непосредственно, все еще используя простую переменную.

Update 2
Это может работать:

// a url 
foreach($urlData as $k=> $v) 
{ 
    $currentSection = &$treeData; 
    // the url pieces 
    foreach($v as $k2=> $v2) 
    { 
    if (!isset($currentSection[$v2])) { 
     $currentSection[$v2] = array(); 
    } 

    $currentSection = &$currentSection[$v2]; 
    } 
} 
+0

Именно здесь я и сейчас, но мне кажется, что мне нужен какой-то рекурсивный метод, чтобы поместить их в правильные слоты, в которые они входят.Я не боюсь рекурсии или чего-то еще, я немного разочарован, работая с этим некоторое время. – Josh

+0

Кроме того, я обновил свой вопрос, включив в него бит, который у меня есть сейчас, а не что-то отдаленное. – Josh

+0

Я думаю, что ответ теперь в моем ответе. Он может работать (он не проверен, и я даже не уверен, что это работает в PHP) –

1

http://ideone.com/S9pWw

$arr = array(
    '/', 
    '/404/', 
    '/abstracts/', 
    '/abstracts/edit/', 
    '/abstracts/review/', 
    '/abstracts/view/', 
    '/admin/', 
    '/admin/ads/', 
    '/admin/ads/clickcounter/', 
    '/admin/ads/delete/', 
    '/admin/ads/edit/', 
    '/admin/ads/list/', 
    '/admin/ads/new/', 
    '/admin/ads/sponsordelete/', 
    '/admin/ads/sponsoredit/', 
    '/admin/ads/sponsornew/', 
    '/admin/ads/stats/', 
    '/admin/boilerplates/', 
    '/admin/boilerplates/deleteboiler/', 
    '/admin/boilerplates/editboiler/', 
    '/admin/boilerplates/newboilerplate/', 
    '/admin/calendar/event/add/', 
    '/admin/calendar/event/copy/'); 

$result = array(); 
foreach ($arr as $node) { 
    $result = magic($node, $result); 
} 

var_dump($result); 

function magic($node, $tree) 
{ 
    $path = explode('/', rtrim($node, '/')); 

    $original =& $tree; 

    foreach ($path as $node) { 
     if (!array_key_exists($node, $tree)) { 
      $tree[$node] = array(); 
     } 

     if ($node) { 
      $tree =& $tree[$node]; 
     } 
    } 

    return $original; 
} 
0

Вы могли бы рассмотреть вопрос о преобразовании текста в JSON строку, а затем с помощью json_decode() для создания структуры.

1

Моя версия:

<?php 
$srcArray = array(
    0 => '/', 
    1 => '/404/', 
    2 => '/abstracts/', 
    3 => '/abstracts/edit/', 
    4 => '/abstracts/review/', 
    5 => '/abstracts/view/', 
    6 => '/admin/', 
    7 => '/admin/ads/', 
    // .... 
); 
$tree = array(); 
foreach($srcArray as $str){ 
    $tmp = &$tree; 
    $parts = explode('/', rtrim($str, '/')); 
    foreach($parts as $part){ 
     if(!array_key_exists($part, $tmp)){ 
      $tmp[$part] = array(); 
     } 
     $tmp = &$tmp[$part]; 
    } 
} 
var_dump($tree); 
2

Я знаю, что ты не просил кусок кода, но я бы просто назвать это Пети сервировку:

$map = array(); 
foreach($urls as $url) { 
    $folders = explode('/', trim($url, '/')); 

    applyChain($map, $folders, array()); 
} 

function applyChain(&$arr, $indexes, $value) { //Here's your recursion 
    if(!is_array($indexes)) { 
     return; 
    } 

    if(count($indexes) == 0) { 
     $arr = $value; 
    } else { 
     applyChain($arr[array_shift($indexes)], $indexes, $value); 
    } 
} 

Это довольно просто. Мы разделяем каждый URL-адрес на свои папки (удаляя конечные и ведущие косые черты), а затем прокладываем путь по цепочке массивов, пока не дойдем до папки, указанной в URL-адресе. Затем мы размещаем новый пустой массив и переходим к следующему URL-адресу.

1
<?php 
$old_array = array("/", "/404/", "/abstracts/", "/abstracts/edit/", "/abstracts/review/", "/rrl/"); 
$new_array = array(); 

foreach($old_array as $woot) { 
    $segments = explode('/', $woot); 
    $current = &$new_array; 
    for($i=1; $i<sizeof($segments); $i++) { 
     if(!isset($current[$segments[$i]])){ 
      $current[$segments[$i]] = array(); 
     } 
     $current = &$current[$segments[$i]]; 
    } 
} 

print_r($new_array); 

?> 
Смежные вопросы