【问题标题】:Convert array of strings into multi-dimensional array [closed]将字符串数组转换为多维数组[关闭]
【发布时间】:2018-03-13 23:05:05
【问题描述】:

如何转换字符串数组:

[
`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`,
]

像这样进入多维

【问题讨论】:

  • 使用循环。一旦你得到了一些代码,以及关于所述代码的问题,请回来,我们会尽力提供帮助。
  • 在您的实际问题中发布您的屏幕截图中包含的任何内容,假设它是一个数组布局。我实际上在这个网站上看不到图片。
  • 我得到了结果 joxi.ru/1A5XWQJhnPRoB2 。这是由循环中的代码完成的 $elements = getDn($raw_dn); $elements = array_values($elements); $字符串 = ''; $val = ''; $closer = ''; for ($i = 0; $i "' . $elements[$i] . '","children"=>' . $val 。 ''; if ($i > 0) $closer .= ']'; } $string .= $closer; eval("\$array = $string;");

标签: php arrays algorithm recursion


【解决方案1】:

复杂的解决方案:

/**
 * 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
                        (
                        )
                )
        )
)

【讨论】:

  • 非常感谢你,罗曼!!
  • @игорь88,不客气
【解决方案2】:
$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)
);

【讨论】:

  • 非常感谢你,萨米奇!!实际上我已经付出了很多努力来解决这个问题。一开始我一直在使用递归。而这种方式一直没有奏效。后来我在这里问了问题
  • @игорь88 你绝对可以递归地解决这个问题,但是一旦你的问题不再是微不足道的,递归解决方案就会变得更加复杂,难以想象,这让我很头疼。 [可能与树有关吗?] 下次您发布问题时,您绝对应该包含您尝试过的代码,以便我们知道您不是在寻找免费代码,以便我们有一个起点来帮助您。
  • 这就是答案。撇开关于其他人使用 eval 的元咆哮,这应该通过 cmets 表达并对有问题的答案投反对票,而不是作为其他有用答案的一部分。 :)
  • 萨米奇,谢谢!下次我会遵守规则的,给您带来的不便,我深表歉意
  • @salathe 好吧,现在冒犯性的答案已被删除,所以 meta rant 看起来就像一个疯子的胡言乱语,所以我将不得不弄清楚如何最好地编辑它:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
相关资源
最近更新 更多