如何减少 5 级深度数组的嵌套 foreaches

How to reduce the nested foreaches for a 5-levels deep array

我有一个 PHP 树结构(数组最大深度:5):

$arr = array(
    '31' => array(
        'Amsterdam' => array(),
        'Rotterdam' => array(),
        'Den Haag' => array(),
        'Utrecht' => array(),
        'Eindhoven' => array(),
        'Tilburg' => array(),
        'Almere' => array(
            '036' => array(
                'BU00340212' => array(
                    'name' => 'Muziekwijk Noord',
                    'residents' => array(
                        'Henk',
                        'Dirk',
                        'Jaap',
                    ),
                ),
                'BU00340213' => array(
                    'name' => 'Muziekwijk Zuid',
                    'residents' => array(
                        'Wim',
                        'Pim',
                        'Jim',
                        'Tim',
                    ),
                ),
            )
        ),
        'Groningen' => array(),
        'Breda' => array(),
        'Nijmegen' => array(),
    )
);

我想要这样的输出:

Almere(netnummer: 036)(cbscode: BU00340212): Henk
Almere(netnummer: 036)(cbscode: BU00340212): Dirk
Almere(netnummer: 036)(cbscode: BU00340212): Jaap
Almere(netnummer: 036)(cbscode: BU00340213): Wim
Almere(netnummer: 036)(cbscode: BU00340213): Pim
Almere(netnummer: 036)(cbscode: BU00340213): Jim
Almere(netnummer: 036)(cbscode: BU00340213): Tim

所以我自己做了一些编码。下面的代码产生我想要的输出。

foreach($arr as $unitKey => $citySet){

    foreach($citySet as $cityName => $cityData){

        if($cityName === 'Almere'){

            $almere = $citySet[$cityName];

            foreach($almere as $netnummer => $netData){

                foreach($netData as $cbsCode => $data){

                    foreach($data['residents'] as $residents){
                        echo $cityName . '(netnummer: '. $netnummer .')(cbscode: '. $cbsCode .'): ' . $residents . '<br>';
                    }
                }
            }
        }
    }
}

上面显示的代码使用了 5 个 foreach,我怀疑这是否是个好主意。所以我试着像这样减少几个 foreaches:

$arrB = $arr['31']['Almere']['036'];
foreach($arrB as $k => $netData){
    foreach($netData as $field => $fieldData){
        if($field === 'residents') {
            foreach($fieldData as $resident){
                echo 'Almere(netnummer: 036)(cbscode: '. $k .'): ' . $resident . '<br>';
            }
        }
    }
}

上面显示的代码使用了 3 个 foreach。那是因为它没有遍历整棵树。

我想用 1 个 foreach 遍历整棵树,并生成我想要的输出。所以我在考虑将 RecursiveArray 与 RecursiveIteratorIterator 结合使用,但如果我使用这种方法,我将无法获得 cbscode。自己看看:

$recursiveArrayIterator = new RecursiveArrayIterator($arr);
$recursiveIteratorIterator = new RecursiveIteratorIterator($recursiveArrayIterator);
foreach($recursiveIteratorIterator as $k => $v){
    if($k !== 'name'){
        echo 'Almere(netnummer: 036)(cbscode: ???): ' . $v . '<br>';
    }
}

Q1:是否可以用一个 foreach 遍历树结构并显示输出?

Q2:如果可以的话,能给个代码吗?如果不是,是否可以将使用的 foreach 数量减少到 2 个?

-- 编辑--

问(改写):完全遍历 5 级深度数组的最易读方法是什么?

您可以将其缩短为:

$arrB = $arr['31']['Almere']['036'];
foreach($arrB as $code => $val) {
    if (isset($val["residents"])) {
        $prefix = 'Almere(netnummer: 036)(cbscode: '. $code .'): ';
        echo $prefix . implode('<br>' . $prefix, $val["residents"]) . '<br>';
    }
}

实例:3v4l

我在这个问题上投入了一些时间,并提出了一种函数式编程方法:

function recursive($data, $countryCode = null, $countryData = null, $city = null, $cityData = null, $netNummer = null, $netData = null, $cbscode = null, $cbsData = null, $residents = null){

    if($residents){
        $resident = array_shift($residents);
        echo $city . '(netnummer: ' . $netNummer . ')(cbscode: ' . $cbscode .'): ' . $resident . '<br>';

        if($residents){
            recursive($data, $countryCode, $countryData, $city, $cityData, $netNummer, $netData, $cbscode, $cbsData, $residents);
        }

        return null;
    }

    if($cbscode && $cbsData){
        $residents = $cbsData['residents'];
        recursive($data, $countryCode, $countryData, $city, $cityData, $netNummer, $netData, $cbscode, $cbsData, $residents);
    }

    if($countryCode && $countryData && $netData){
        $cbscode = key($netData);
        $cbsData = array_shift($netData);
        recursive($data, $countryCode, $countryData, $city, $cityData, $netNummer, $netData, $cbscode, $cbsData);
    }

    if($countryCode && $countryData && $city && $cityData){
        $netNummer = key($cityData);
        $netData = array_shift($cityData);
        recursive($data, $countryCode, $countryData, $city, $cityData, $netNummer, $netData);
    }

    if($countryCode && $countryData){
        $city = key($countryData);
        $cityData = array_shift($countryData);
        recursive($data, $countryCode, $countryData, $city, $cityData);
    }

    if($data){
        $countryCode = key($data);
        $countryData = array_shift($data);
        if($countryData){
            recursive($data, $countryCode, $countryData);
        }
    }

    return null;
}

recursive($arr);

在线来源:https://3v4l.org/rsf5o