转换数组关联递归
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();');
};
我们有一个包含以下值的数组:
$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();');
};