如何在循环内部取消设置foreach循环主数组(正在迭代的那个)?

时间:2015-09-30 19:28:43

标签: php foreach

我有两个foreach循环,如下所示。

这个想法是按顺序处理类型1之前的类型2。下面的代码工作正常,但我想知道如何使用unset来实现相同的结果,而不是使用另一个数组$processed来跟踪处理的内容。

我知道PHP foreach克隆/复制$data数组以进行迭代。换句话说,是否有可能unset在第二个$data循环中从foreach输入2并且不知何故首先foreach循环跳过它们?

我知道PHP foreach clones / copies数组用于迭代。

  $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

2 个答案:

答案 0 :(得分:0)

这是一个更简单的版本,不需要取消任何设置。它只是测试类型。对于每个类型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 1}}包含所有类型2条目。然后你只需使用简单的嵌套循环:

foreach ($dataType1 as $firstValue) {
    foreach ($dataType2 as $secondValue) {
        echo $secondValue['type'] . " processed " . "<br/>";
    }
    echo $firstValue['type'] . " processed" . "<br/>";
}

答案 1 :(得分:0)

重做我的答案,以配合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);

这个函数会修改你的数组,在它通过它的过程中不断地取消设置。