2015-05-26 3 views
0

Я работаю с системой разрешений, в которой мне нужно преобразовать массив одного уровня (разделенный символами подчеркивания) в многомерный массив. Любая помощь с функцией, которая исправляет это?PHP Преобразование массива

Входной массив:

Array 
(
    [0] => dashboard 
    [1] => dashboard_read 
    [2] => dashboard_update 
    [3] => dashboard_create 
    [4] => dashboard_delete 
    [5] => dashboard_search 
    [6] => timeplan_event_read 
    [7] => timeplan_event_search 
    [8] => timeplan_read 
    [9] => timeplan_search 
    [10] => webhotel 
    [11] => webhotel_read 
    [12] => webhotel_update 
    [13] => webhotel_create 
    [14] => webhotel_delete 
    [15] => webhotel_search 
) 

Выходной массив:

array(
    'dashboard' => array(
     'read', 
     'update', 
     'create', 
     'delete', 
     'search' 
    ), 
    'timeplan' =>array(
     'read', 
     'search', 
     'event' => array(
      'read', 
      'search' 
     ) 
    ), 
    'webhotel' =>array(
     'read', 
     'update', 
     'create', 
     'delete', 
     'search' 
    ), 
) 
+1

Я думаю, вы должны пойти с 'foreach' петли и' взрываются ('_', ...) '. – TiMESPLiNTER

+1

Я бы порекомендовал вам придумать более однородную структуру. В настоящее время трудно предсказать, является ли данное разрешение ключом массива с дополнительными ключами или значением. Это будет больно работать. Что-то вроде '['name' => .., 'children' => [..]]' упростит это. Здесь могут помочь и некоторые классы. – deceze

+2

Как намек на будущее, его довольно приятно, если вы можете предоставить свои входные данные как исходный код с возможностью копирования. – take

ответ

0
[[email protected] tmp]$ cat test.php 
<?php 

$array = array("dashboard","dashboard_read","dashboard_update","dashboard_create","dashboard_delete","dashboard_search","timeplan_event_read","timeplan_event_search","timeplan_read","timeplan_search","webhotel","webhotel_read","webhotel_update","webhotel_create","webhotel_delete","webhotel_search"); 


function build_arr($array, $delim='_') 
{ 
    $output = array(); 
    foreach($array as $key) 
    { 
    $main = explode($delim, $key); 
    if (count($main) < 2) 
     continue; 

     $bottom = &$output; 
     while(count($main) > 1) 
     { 
       $sub = array_shift($main); 
       if (!isset($bottom[$sub])) 
       { 
        $bottom[$sub] = array(); 
       } 
        $bottom = &$bottom[$sub]; 
     } 
       $bottom[] = $main[count($main)-1]; 
    } 
    return $output; 
} 

    // Input 
    print_r($array); 

    // Output 
    print_r(build_arr($array)); 


?> 

Выход

[[email protected] tmp]$ php test.php 
Array 
(
    [0] => dashboard 
    [1] => dashboard_read 
    [2] => dashboard_update 
    [3] => dashboard_create 
    [4] => dashboard_delete 
    [5] => dashboard_search 
    [6] => timeplan_event_read 
    [7] => timeplan_event_search 
    [8] => timeplan_read 
    [9] => timeplan_search 
    [10] => webhotel 
    [11] => webhotel_read 
    [12] => webhotel_update 
    [13] => webhotel_create 
    [14] => webhotel_delete 
    [15] => webhotel_search 
) 

Array 
(
    [dashboard] => Array 
     (
      [0] => read 
      [1] => update 
      [2] => create 
      [3] => delete 
      [4] => search 
     ) 

    [timeplan] => Array 
     (
      [event] => Array 
       (
        [0] => read 
        [1] => search 
       ) 

      [0] => read 
      [1] => search 
     ) 

    [webhotel] => Array 
     (
      [0] => read 
      [1] => update 
      [2] => create 
      [3] => delete 
      [4] => search 
     ) 

) 
+1

Спасибо! Это работает! :) – fl0pp

5

Вы можете перемещаться через массив и взрываются на «_'- характер. После этого вы можете просто создать свой новый массив в нужном древовидном формате.

<?php 
$tmp = array("dashboard","dashboard_read","dashboard_update","dashboard_create","dashboard_delete","dashboard_search","timeplan_event_read","timeplan_event_search","timeplan_read","timeplan_search","webhotel","webhotel_read","webhotel_update","webhotel_create","webhotel_delete","webhotel_search"); 

$newarray = array(); 

foreach ($tmp as $value) { 
    $parts = explode("_", $value); 
    if (count($parts) < 2) 
     continue; 
    $arr = &$newarray; 
    for ($i=0;$i<count($parts)-1;$i++) { 
     if (!array_key_exists($parts[$i], $arr)) { 
      $arr[$parts[$i]] = array(); 
     } 
     $arr = &$arr[$parts[$i]]; 
    } 
    $arr[] = $parts[count($parts)-1]; 
} 

print_r($newarray); 

--- Выход ---

$ php -f tmp.php 
Array 
(
    [dashboard] => Array 
     (
      [0] => read 
      [1] => update 
      [2] => create 
      [3] => delete 
      [4] => search 
     ) 

    [timeplan] => Array 
     (
      [event] => Array 
       (
        [0] => read 
        [1] => search 
       ) 

      [0] => read 
      [1] => search 
     ) 

    [webhotel] => Array 
     (
      [0] => read 
      [1] => update 
      [2] => create 
      [3] => delete 
      [4] => search 
     ) 

) 
+0

Это создает дополнительный элемент '[timeplan] => Array ([0] => event)' при попытке исходных данных. – evilive

+0

Спасибо за проголосовать, но когда я тестирую его с входными данными из op, он работает как шарм. Без проблем. – take

+1

Он работает с данным образцом ввода, если ваши исходные данные отличаются от текущего, это ваша проблема, а не тот, на который он ответил, хорошо сделан [принять] (http://stackoverflow.com/users/904665/take) –

0

Я была такая же проблема раз назад, но я не знаю, как код выглядит точно. Моя идея состояла в том, чтобы написать рекурсивную функцию, которая explode('_', $string) текущее разрешение, и итерации по частям. И там он будет делать что-то вроде

if count $parts === 1: 
    $result[] = $parts 
else: 
    $result[$parts[0]] = recursive call ($parts, $result) 

Я надеюсь, что это приведет вас на правильном пути ...

0

Нет ограничений глубины.

$arr = []; 

while($path = array_pop($x)) 
{ 
    $parts = explode('_',$path); 
    $value = array_pop($parts); 
    $cell = &$arr; 
    while($part = array_shift($parts)){ 
     if (!isset($cell[$part])) $cell[$part] = []; 
     $cell = &$cell[$part]; 
    } 
    if (!array_key_exists($value, $cell)) 
     array_push($cell, $value); 
} 

Выход:

array:3 [ 
    "webhotel" => array:5 [ 
    0 => "search" 
    1 => "delete" 
    2 => "create" 
    3 => "update" 
    4 => "read" 
    ] 
    "timeplan" => array:3 [ 
    0 => "search" 
    1 => "read" 
    "event" => array:2 [ 
     0 => "search" 
     1 => "read" 
    ] 
    ] 
    "dashboard" => array:5 [ 
    0 => "search" 
    1 => "delete" 
    2 => "create" 
    3 => "update" 
    4 => "read" 
    ] 
] 
Смежные вопросы