php - 如何从 PHP 中的关联数组构建多维数组树?
问题描述
我正在尝试通过将“s”和“d”键字符串值替换为它们各自的键“bandnumber”数组来从关联数组构建多维数组树,但似乎无法破解它。我只能使它适用于数组的第一个节点。
例如,我有以下数组:
$coiArray = array (
array('bandnumber' => '02-BELG-2129929', 's' =>'94-BELG-3237180', 'd' => '96-BELG-3156295' ),
array('bandnumber' => '94-BELG-3237180', 's' =>'88-BELG-3206112', 'd' => '88-BELG-3206173' ),
array('bandnumber' => '88-BELG-3206112', 's' =>'81-BELG-3238253', 'd' => '87-BELG-3008002' ),
array('bandnumber' => '88-BELG-3206173', 's' =>'', 'd' => '' ),
array('bandnumber' => '96-BELG-3156295', 's' =>'88-BELG-3206112', 'd' => '85-BELG-3049648' ),
array('bandnumber' => '85-BELG-3049648', 's' =>'', 'd' => '' ),
array('bandnumber' => '81-BELG-3238253', 's' =>'', 'd' => '' ),
array('bandnumber' => '87-BELG-3008002', 's' =>'', 'd' => '' ),
);
我正在尝试以编程方式将上述数组转换为以下多维数组树:
$coiNestedArray = array('bandnumber' => '02-BELG-2129929',
's' => array('bandnumber' => '94-BELG-3237180',
's' => array('bandnumber' => '88-BELG-3206112',
's' => array('bandnumber' => '81-BELG-3238253',
's' =>'',
'd' => ''
),
'd' => array('bandnumber' => '87-BELG-3008002',
's' =>'',
'd' => ''
)
),
'd' => array('bandnumber' => '88-BELG-3206173',
's' =>'',
'd' => ''
)
),
'd' => array('bandnumber' => '96-BELG-3156295',
's' => array('bandnumber' => '88-BELG-3206112',
's' => array('bandnumber' => '81-BELG-3238253',
's' =>'',
'd' => ''
),
'd' => array('bandnumber' => '87-BELG-3008002',
's' =>'',
'd' => ''
)
),
'd' => array('bandnumber' => '85-BELG-3049648',
's' =>'',
'd' => ''
)
)
);
这是迄今为止我最接近的一次,但它只更新数组的第一个节点:
function findKey($coiarray, $bandnumber){
$thisCol = array_column($coiarray, 'bandnumber');
$found_key = array_search($bandnumber, $thisCol);
return $found_key;
}
foreach ($coiArray as $key => $value) {
$s = '';
$found_key = findKey($coiArray,$coiArray[$key]['s']);
if(isset($coiArray[$found_key])){
$s = $coiArray[$found_key];
}
$d = '';
$found_key = findKey($coiArray,$coiArray[$key]['d']);
if(isset($coiArray[$found_key])) {
$d = $coiArray[$found_key];
}
$coiArray[$key] = array('bandnumber' => $coiArray[$key]['bandnumber'], 's' => $s, 'd' => $d );
}
我将在此处重新发布数组的整个转储,但这是$coiArray
, from的第一个节点var_dump($coiArray)
,您会注意到所有最内层嵌套的 ["s"] 和 ["d"] 键都是字符串各自的数组。
[0]=>
array(3) {
["bandnumber"]=>
string(15) "02-BELG-2129929"
["s"]=>
array(3) {
["bandnumber"]=>
string(15) "94-BELG-3237180"
["s"]=>
string(15) "88-BELG-3206112"
["d"]=>
string(15) "88-BELG-3206173"
}
["d"]=>
array(3) {
["bandnumber"]=>
string(15) "96-BELG-3156295"
["s"]=>
string(15) "88-BELG-3206112"
["d"]=>
string(15) "85-BELG-3049648"
}
}
下面的示例是我手动创建的 中的第一个节点$coiNestedArray
,以说明我想要实现的目标。请注意,每个 ["s"] 和 ["d"] 都是一个数组,派生自$coiArray
.
array(3) {
["bandnumber"]=>
string(15) "02-BELG-2129929"
["s"]=>
array(3) {
["bandnumber"]=>
string(15) "94-BELG-3237180"
["s"]=>
array(3) {
["bandnumber"]=>
string(15) "88-BELG-3206112"
["s"]=>
array(3) {
["bandnumber"]=>
string(15) "81-BELG-3238253"
["s"]=>
string(0) ""
["d"]=>
string(0) ""
}
["d"]=>
array(3) {
["bandnumber"]=>
string(15) "87-BELG-3008002"
["s"]=>
string(0) ""
["d"]=>
string(0) ""
}
}
["d"]=>
array(3) {
["bandnumber"]=>
string(15) "88-BELG-3206173"
["s"]=>
string(0) ""
["d"]=>
string(0) ""
}
}
我该如何解决这个问题?
解决方案
您需要创建一个以波段号为键的关联数组,因此您可以直接按波段号查找行。然后通过引用访问孩子并用该关联数组中的相应值替换每个孩子。
可选地检测哪个波段号从未被引用为孩子:它是根。但是,如果您知道根波段号,或者您知道它始终是第一个输入行中的那个,那么您可以跳过最后一步。最后提取该根的值(假设正好有一个):
// Key the rows by their bandnumber:
foreach($coiArray as $row) {
$hash[$row["bandnumber"]] = $row;
}
foreach($hash as &$row) {
// Replace children with the corresponding row in the hash
foreach(["s","d"] as $prop) {
$child = $row[$prop];
if (!isset($hash[$child])) continue;
$row[$prop] =& $hash[$child];
$children[] = $child; // Keep track of non-root bandnumbers
}
}
// Only needed when you don't know which bandnumber is the root:
$root = current(array_diff(array_keys($hash), $children, ["s","d"]));
$result = $hash[$root];
推荐阅读
- python - 对列表列表进行排序以查找共享变体
- python - Python lxml iterparse按属性大xml文件排序
- java - 尝试在浏览器上捕获音频时的 Http 退出状态(由 servlet 设置)
- c - 如何列出 0 和 n 之间的数字,其中数字的总和及其正除数将构成一个完美的平方?
- reactjs - Redux-Observable - Typescript 错误:“类型‘{}’中缺少属性‘类型’,但类型中需要”
- ocaml - 有没有办法让自动格式化程序保留一元代码风格?
- python - 如何从字符串列表中删除空格
- python - 将 Web 响应保存到文件
- angular - Ionic 4:使用环境配置选项运行 Livereload 时出现问题
- racket - 修复 VSCode 中的球拍缩进?