将分隔值的平面数组转换为分层数组

问题描述 投票:0回答:4

我正在使用一个权限系统,我必须将单级数组(用下划线分隔)转换为多维数组。有解决此问题的功能吗?

输入数组:

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'
    ),
)
php arrays multidimensional-array hierarchical
4个回答
4
投票

您可以迭代数组并在“_”字符上爆炸。之后,您可以简单地以所需的树格式构建新数组。

<?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
投票
[akshay@localhost 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) );


 ?>

输出

 [akshay@localhost 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
         )

 )

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"
  ]
]
© www.soinside.com 2019 - 2024. All rights reserved.