我想为每个元素和sub以及sub的sub设置id或索引,依此类推
<?php
$data = array(
array(
'title' => 'a',
'children' => array(
array(
'title' => 'a-a',
'children' => array(
array(
'title' => 'a-a-a',
'children' => array(
)
)
)
),
array(
'title' => 'a-b',
'children' => array(
)
)
)
),
array(
'title' => 'b',
'children' => array(
)
)
);
?>
我正在寻找与递归一起使用的PHP代码或函数来添加索引键和数字(desc)这样的输出
<?php
$data = array(
array(
'index' => 1,
'children' => array(
array(
'index' => 2,
'children' => array(
array(
'index' => 3,
'children' => array(
)
)
)
),
array(
'index' => 4,
'children' => array(
)
)
)
),
array(
'index' => 5,
'children' => array(
)
)
);
?>
答案 0 :(得分:2)
曾几何时,有一项研究得出的结论是,年轻的padawan程序员在成为绝地高级程序员的过程中面临的最大挑战是:
[...]有三个主要的语义障碍使新手命令式程序员绊倒。他们是:
- 分配和顺序
- 递归 / iteration
- 并发
我第一次在Jeff Atwood的博客文章Separating Programming Sheep from Non-Programming Goats中遇到了这个理论,该论文基于科学论文:The camel has two humps (working title)
这是实现您想要的代码(减去仅{em>可视化步骤的echo
次调用):
function addIndexRecursive(&$data) {
static $index = 0;
echo "The index is: $index" . PHP_EOL;
foreach ($data as &$item) {
$index++;
echo "The index was incremented: {$index}" . PHP_EOL;
$item = array('index' => $index) + $item;
echo "Add the index to the item with title: {$item['title']}" . PHP_EOL;
if (count($item['children']) > 0) {
echo "This item has children so call the index function" . PHP_EOL;
addIndexRecursive($item['children'], $index);
// this else branch is only for illustration purposes only
} else {
echo "There are no children therefore I stop" . PHP_EOL;
}
}
}
所以请稍微剖析一下。
首先要注意的是:我pass the array by reference。这只是一个品味问题,我更喜欢直接修改数组而不是构建另一个副本。
static $index
将帮助我跟踪当前索引,并且会在遇到每个项目时递增。让我们看看这个static
做了什么样的黑魔法(根据Variable scope):
再次静态变量仅存在于本地函数作用域中,但在程序执行离开此作用域时它不会丢失其值。
foreach ($data as &$item)
我希望元素通过引用传递,这样我就可以直接在循环中修改它们。
现在我们讨论了实现细节,让我们看看该函数的 back-trace 是什么:
addIndexRecursive was call and the index is: 0
The index was incremented: 1
Add the index to the item with title: a
This item has children so call the function
addIndexRecursive was call and the index is: 1
The index was incremented: 2
Add the index to the item with title: a-a
This item has children so call the function
addIndexRecursive was call and the index is: 2
The index was incremented: 3
Add the index to the item with title: a-a-a
There are no children therefore I stop
The index was incremented: 4
Add the index to the item with title: a-b
There are no children therefore I stop
The index was incremented: 5
Add the index to the item with title: b
There are no children therefore I stop
你会继续遇到这类问题,所以越早掌握递归概念越好。
答案 1 :(得分:1)
这是“嵌套数组”的示例,其中各个数组需要:
1) an entry to be added: 'index' => <incrementing number> where there is a 'children' entry in the array.
2) an entry to be removed where: 'title' exists in the array.
由于数组可以“嵌套”,因此“递归”是处理“数据”数组的最合适方式。
我发现更容易修改数组“就地”而不是构建'output'数组。因此'数组引用'(&amp; $ arrayEntry)使用了很多。
我使用提供的测试数据并测试'required'数组和'indexed'数组在'结构'方面是相同的。
这是经过测试的代码:Windows XP上的PHP 5.3.18。的 Working code at: viper-7.com 强>
完成工作的功能:
function addChildrenIndex(&$destData, &$idxNew)
{
foreach($destData as $currentKey => &$currentValue) { // pass be reference so i can amend it
if (is_array($currentValue)) { // ensure is 'children' array
if (isset($currentValue['children'])) { // add the 'index' entry
$currentValue['index'] = $idxNew;
$idxNew++;
}
if (isset($currentValue['title'])) { // remove the 'title' entry!
unset($currentValue['title']);
}
// as it is an array we 'recurse' around it - always...
addChildrenIndex($currentValue, $idxNew);
}
}
}
驾驶密码:
$idxNew = 1; // starting index.
// COPY the source data so i can test it later if required...
$indexedData = $data; // output array
addChildrenIndex($indexedData, $idxNew); // re-index the array 'in place'
// echo 'Required Array: <pre>';
// print_r($requiredData);
// echo '</pre>';
// echo 'OutputArray: <pre>';
// print_r($indexedData);
// echo '</pre>';
// test array structures to contain same entries...
var_dump($indexedData == $requiredData, 'ARE EQUAL?');
必需的测试数据:见问题
索引输出:
Array
(
[0] => Array
(
[children] => Array
(
[0] => Array
(
[children] => Array
(
[0] => Array
(
[children] => Array
(
)
[index] => 3
)
)
[index] => 2
)
[1] => Array
(
[children] => Array
(
)
[index] => 4
)
)
[index] => 1
)
[1] => Array
(
[children] => Array
(
)
[index] => 5
)
)