将字符串数组转换为多维数组

时间:2017-10-02 20:05:19

标签: php arrays algorithm recursion

如何转换字符串数组:

[
`ou=HR,ou=Employees,ou=People`,
 `ou=IT,ou=Employees,ou=People`,
`ou=Video,ou=Employees,ou=People`,
 `ou=HR1,ou=HR,ou=Employees,ou=People` ,
`ou=aHR1,ou=HR,ou=Employees,ou=People` ,`ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People`,
]
像这样进入多维度 enter image description here

2 个答案:

答案 0 :(得分:3)

复杂的解决方案:

/**
 * Converts path into array (hierarchically)
 *
 * @param $arr
 *
 */
function pathToArray($arr){
    $result = [];

    $checkItem = function (&$keys, &$a) use(&$checkItem){
        foreach ($keys as $k => $v) {
            if (!isset($a[$v])) {
                $a[$v] = [];
            }
            unset($keys[$k]);
            if (!empty($keys)) $checkItem($keys, $a[$v]);
        }
    };

    foreach ($arr as $path) {
        $curren_arr = [];
        $keys = array_reverse(array_map(function($v){
            return str_replace('ou=', '', $v);
        }, explode(',', $path)));

        $checkItem($keys, $result);
    }

    return $result;
}

$arr = [
    'ou=HR,ou=Employees,ou=People', 'ou=IT,ou=Employees,ou=People',
    'ou=Video,ou=Employees,ou=People', 'ou=HR1,ou=HR,ou=Employees,ou=People' ,
    'ou=aHR1,ou=HR,ou=Employees,ou=People' ,'ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People',
];

print_r(pathToArray($arr));

输出:

Array
(
    [People] => Array
        (
            [Employees] => Array
                (
                    [HR] => Array
                        (
                            [HR1] => Array
                                (
                                    [HR2] => Array
                                        (
                                        )
                                )

                            [aHR1] => Array
                                (
                                )
                        )

                    [IT] => Array
                        (
                        )

                    [Video] => Array
                        (
                        )
                )
        )
)

答案 1 :(得分:3)

$input = [
    'ou=HR,ou=Employees,ou=People',
    'ou=IT,ou=Employees,ou=People',
    'ou=Video,ou=Employees,ou=People',
    'ou=HR1,ou=HR,ou=Employees,ou=People',
    'ou=aHR1,ou=HR,ou=Employees,ou=People',
    'ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People',
];

$output = [];

foreach( $input as $line ) {
    // split by commas
    $parts = explode(',', $line);
    // remove 'ou='
    $parts = array_map(function($a){return preg_replace('/^ou=/', '', $a);}, $parts);
    // reverse
    $parts = array_reverse($parts);

    // assign the cur pointer to the base of the output array
    $cur = &$output;
    foreach($parts as $part) {
        // create the key if not exists
        if( ! key_exists($part, $cur) ) {
            $cur[$part] = [];
        }
        // assign the cur pointer to the current level in the array
        $cur = &$cur[$part];
    }
}
// unset the reference to avoid future problems if $cur were ever reused.
unset($cur);

var_dump($output);

结果:

array(1) {
  ["People"]=>
  array(1) {
    ["Employees"]=>
    array(3) {
      ["HR"]=>
      array(2) {
        ["HR1"]=>
        array(1) {
          ["HR2"]=>
          array(0) {
          }
        }
        ["aHR1"]=>
        array(0) {
        }
      }
      ["IT"]=>
      array(0) {
      }
      ["Video"]=>
      array(0) {
      }
    }
  }
}

修改

你的书呆子狙击了我。有一个递归解决方案,您希望将输入数组视为通过树的路径列表。因此,您希望沿给定路径遍历树,并根据需要添加缺少的节点。虽然它实际上与普通循环代码几乎完全相同。

$input = [
    'ou=HR,ou=Employees,ou=People',
    'ou=IT,ou=Employees,ou=People',
    'ou=Video,ou=Employees,ou=People',
    'ou=HR1,ou=HR,ou=Employees,ou=People',
    'ou=aHR1,ou=HR,ou=Employees,ou=People',
    'ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People',
];

function add_path_to_tree(&$root, $path) {
    $key = array_shift($path);

    if( ! key_exists($key, $root) ) {
        $root[$key] = [];
    }
    if( empty($path) ) { return; }
    return add_path_to_tree($root[$key], $path);
}

function solve_recurse($input) {
    $output = [];
    foreach( $input as $line ) {
        $parts = array_reverse(
            array_map(
                function($a){return preg_replace('/^ou=/', '', $a);},
                explode(',', $line)
            )
        );
        add_path_to_tree($output, $parts);
    }
    return $output;
}

var_dump(
    solve_recurse($input)
);