转换数组关联递归

Transform array associative recursive

我们有一个包含以下值的数组:

$a = array("a", "a.b", "a.b.c", "X", "X.Y", "X.Y.Z");

而目标是,将第一个数组修改为以下结构:

$a = array(
     "a" => array(
         "b" => array(
             "c" => array(),
         ),
     ),
     "X" => array(
         "Y" => array(
             "Z" => array(),
         ),
     ),
);

我为什么要问?我的一位客户有 table 商店类别。这些类别在一栏中(简化!):

 +-----------------------+
 |id |       name        |
 +---|-------------------+
 | 4 | A                 |
 | 5 | A.B               |
 | 6 | A.B.C             |
 | 7 | X                 |
 | 8 | X.Y               |
 | 9 | X.Y.Z             |
 +-----------------------+

我如何使用 PHP 执行此操作?

编辑:

我现在的"solution / trys"

<?php

$arr = array(
    "a",
    "a.b",
    "a.b.c",
    "x",
    "x.y",
    "x.y.z",
);

$container = array();
$updateMe = array();

foreach($arr as $key => $value) {
    $cleanName = explode(".", $value);

    foreach($cleanName as $keyArray => $valueArray) {
        for($c = 0;$c<$keyArray+1;$c++) {
            $updateMe[$cleanName[$c]] = array();
        }


    } 

    $container[$cleanName[0]] = $updateMe;
    unset($updateMe);
}

echo "<pre>";
var_dump($container);
echo "===\r\n";

我的输出:

array(2) {
  ["a"]=>
  array(3) {
    ["a"]=>
    array(0) {
    }
    ["b"]=>
    array(0) {
    }
    ["c"]=>
    array(0) {
    }
  }
  ["x"]=>
  array(3) {
    ["x"]=>
    array(0) {
    }
    ["y"]=>
    array(0) {
    }
    ["z"]=>
    array(0) {
    }
  }
}
===

解决方案

<?php

$arr = array(
    "a",
    "a.b",
    "a.b.c",
    "x",
    "x.y",
    "x.y.z",
);

$array = array();
$test = array();

foreach($arr as $key => $text) {
    $array = array();
    foreach(array_reverse(explode('.', $text)) as $key) $array = array($key => $array);

    $test[] = $array;
}

echo "<pre>";
var_dump($test);
echo "===\r\n";

您可以使用已接受的答案 from this question, or this answer from the same question to get a good starting point(我将使用第二个答案,因为在本例中它更短)。

$out = array();
foreach ($a as $string) {
    $array = array();
    foreach(array_reverse(explode('.', $string)) as $key) {
        $array = array($key => $array);
    }
    $out[] = $array;
}

这将为您提供一个基于数字键的数组,因此您可以使用 an answer from this question:

移出数组的第一层
$out = call_user_func_array('array_merge', $out);

还有你的result

Array
(
    [a] => Array
        (
            [b] => Array
                (
                    [c] => Array
                        (
                        )

                )

        )

    [X] => Array
        (
            [Y] => Array
                (
                    [Z] => Array
                        (
                        )

                )

        )

)

我喜欢在 PHP 中使用引用。这可能不是最好的解决方案,但它似乎有效。

<?php
$arr = array(
    "a",
    "a.b",
    "a.b.c",
    "x",
    "x.y",
    "x.y.z",
);

$output = array();

foreach($arr as $path){
    // Create a reference to the array
    // As we go deeper into the path we will move this reference down
    $setArray =& $output;

    foreach(explode('.', $path) as $key){
        // If this key does not exist, create it
        if(!isset($setArray[$key])){
            $setArray[$key] = array();
        }

        // Move the reference down one level,
        // so that the next iteration will create
        // the key at the right level
        $setArray =& $setArray[$key];
    }
}

// Destroy the reference, so that we don't accidently write to it later
unset($setArray);

var_dump($output);

这应该适合你:

<?php

    $a = array("a", "a.b", "a.b.c", "1", "1.2", "1.2.3");
    $results = array();

    function stringToArray($path) {

        $pos = strpos($path, ".");

        if ($pos === false)
            return array($path => "");

        $key = substr($path, 0, $pos);
        $path = substr($path, $pos + 1);

        return array(
            $key => stringToArray($path)
        );

    }

    foreach($a as $k => $v) {
        if(substr_count(implode(", ", $a), $v) == 1)
            $results[] = stringToArray($v);
    }

    $results = call_user_func_array('array_merge', $results);
    print_R($results);

?>

输出:

Array ( [a] => Array ( [b] => Array ( [c] => ) ) [0] => Array ( [2] => Array ( [3] => ) ) )

只是棘手的一个

  $a = array("a", "a.b", "a.b.c", "X", "X.Y", "X.Y.Z");

    $res = array();
    foreach ($a as $str) {
        $str = str_replace('.','"]["',$str);
        $tricky = '$res["'.$str.'"]';
        eval ($tricky.' = array();');
};