我有两个foreach
循环如下:
思路是在处理类型1之前按顺序处理类型2。下面的代码工作得很好,但我想知道如何使用unset
来实现相同的结果,而不是使用另一个数组$processed
来跟踪处理的内容。
我知道PHP foreach克隆/复制$data
数组进行迭代。换句话说,是否有可能在第二个foreach
循环中从$data
到unset
类型2,并且以某种方式第一个foreach
循环跳过它们?
我知道PHP foreach克隆/复制数组用于迭代。
$data = array(
array('type' => 1),
array('type' => 2),
array('type' => 2),
array('type' => 2),
array('type' => 1),
array('type' => 2),
array('type' => 2),
);
$processed = array();
foreach ($data as $firstKey => $firstValue) {
if (in_array($firstKey, $processed)) {
continue;
}
foreach ($data as $secondKey => $secondValue) {
if ($secondValue['type'] == 2) {
echo $secondValue['type'] . " processed " . "<br/>";
$processed[] = $secondKey; // can I use unset here?
}
}
echo $firstValue['type'] . " processed" . "<br/>";
}
希望通过这个更新,我可以表达我的意图。
每个子节点都有对父节点的引用。所有子进程都需要在父进程之前处理。下面的代码应该可以正常工作。您可以尝试一下,下面的代码输出就是期望的行为。如果可能的话,我想用unset
来做。
$data = array(
array('id' => 1, 'ref' => null, 'name' => 'parent 1'),
array('id' => 2, 'ref' => 1, 'name' => 'child 1'),
array('id' => 3, 'ref' => 1, 'name' => 'child 2'),
array('id' => 4, 'ref' => 1, 'name' => 'child 3'),
array('id' => 5, 'ref' => null, 'name' => 'parent 2'),
array('id' => 6, 'ref' => 5, 'name' => 'child 1'),
array('id' => 7, 'ref' => 5, 'name' => 'child 2'),
array('id' => 8, 'ref' => null, 'name' => 'parent 3'),
array('id' => 9, 'ref' => 8, 'name' => 'child 1'),
array('id' => 10, 'ref' => 8, 'name' => 'child 2'),
);
$processed = array();
foreach ($data as $ref => $firstValue) {
if (in_array($ref, $processed)) {
continue;
}
foreach ($data as $secondKey => $secondValue) {
if ($secondValue['ref'] == $firstValue['id']) {
echo $secondValue['id'] . "- " . $secondValue['name'] . " processed " . "<br/>";
$processed[] = $secondKey;
}
}
echo $firstValue['id'] . "- " . $firstValue['name'] . " processed" . "<br/>";
echo "<hr/>";
}
以上代码输出:
2- child 1 processed
3- child 2 processed
4- child 3 processed
1- parent 1 processed
6- child 1 processed
7- child 2 processed
5- parent 2 processed
9- child 1 processed
10- child 2 processed
8- parent 3 processed
这里有一个更简单的版本,不需要取消任何设置。它只是测试类型。对于每个类型1的条目,它首先处理所有类型2的条目,然后处理类型1的条目。
<?php
$data = array(
array('type' => 1),
array('type' => 2),
array('type' => 2),
array('type' => 2),
array('type' => 1),
array('type' => 2),
array('type' => 2),
);
foreach ($data as $firstKey => $firstValue) {
if ($firstValue['type'] == 1) {
foreach ($data as $secondKey => $secondValue) {
if ($secondValue['type'] == 2) {
echo $secondValue['type'] . " processed " . "<br/>";
}
}
echo $firstValue['type'] . " processed" . "<br/>";
}
}
另一种不需要测试内循环类型的方法是简单地创建两个数组:$dataType1
包含$data
中的所有类型1项,$dataType2
包含所有类型2项。然后使用简单的嵌套循环:
foreach ($dataType1 as $firstValue) {
foreach ($dataType2 as $secondValue) {
echo $secondValue['type'] . " processed " . "<br/>";
}
echo $firstValue['type'] . " processed" . "<br/>";
}
重新回答以匹配OP更新的问题。
下面是使用递归函数
实现类似输出的一种方法function processData(&$data, $ref = null)
{
foreach ($data as $key => $value) {
if ($ref !== null && $value['ref'] !== $ref) {
continue;
}
$data = processData($data, $value['id']);
echo $value['id'] . "- " . $value['name'] . " processed" . "<br/>";
unset($data[$key]);
}
return $data;
}
processData($data);
这个函数会修改你的数组,在它运行的过程中不断地取消元素设置。