【问题标题】:PHP: Iterating Through a multidimensional Array (4D)PHP:遍历多维数组(4D)
【发布时间】:2020-09-06 05:11:00
【问题描述】:

我有一个如下结构的多维数组。它模仿了一个文件结构,该结构基于 ./YEAR/MONTH/DAY/FILE.

存储文件
Array
(
    [2019] => Array
        (
            [05] => Array
                (
                    [12] => Array
                        (
                            [0] => default.md
                        )
                )

            [12] => Array
                (
                    [22] => Array
                        (
                            [0] => default.md
                        )
                )
        )

    [2020] => Array
        (
            [05] => Array
                (
                    [19] => Array
                        (
                            [0] => default.md
                        )
                )
        )
)

我正在尝试遍历整个数组并获取每个特定文件的值,同时还获取该指定文件的关联 YEAR、MONTH 和 DAY。

当我试图在一个 for 循环中嵌套多个 foreach 循环时,我的循环已经偏离了。越深入兔子洞,遇到的问题就越多

$post_search = directoryArrayMap("content"); //function that creates the array

$year = array_keys($post_search);

for($i = 0; $i < count($post_search); $i++ ) {
    echo $year[$i] . "<br>";
    foreach($post_search[$year[$i]] as $month => $day ) {
        echo $month[$i] . "<br>";
        foreach($post_search[$key[$month[$i]]] as $day => $post_file ) {
            echo $day . "<br>";
        }
    }
}

我正在寻找迭代多维数组的最佳方法。谢谢。我想要的输出是这样的:

档案一: 年份:2020 月:05 天数:12 文件 B: 年份:2019 月:12 天数:22 文件 C: 年份:2019 月:05 天数:19

目标是与另一个检查“is_file”并显示输出的循环一起运行。

【问题讨论】:

  • 您可能想要使用RecursiveIteratorIterator Object,而不是嵌套一大堆foreach 循环。这里的想法是它将您的数组扁平化为单个 foreach 循环,但您仍然可以跟踪您的深度以及您在嵌套数组结构中的位置。使用它,连同getDepthgetSubIteratorkey 方法的组合,您可以遍历您的树并在您点击代表文件的任何非数组值时从树中提取您需要的任何键。

标签: php for-loop multidimensional-array foreach


【解决方案1】:

通过使用一系列嵌套的foreachkey =&gt; value 迭代器,你可以获得你想要的输出;关键是在到达循环底部之前不要输出日期部分:

foreach ($post_search as $year => $months) {
    foreach ($months as $month => $days) {
        foreach ($days as $day => $files) {
            foreach ($files as $file) {
                echo "File $file:\nYear: $year\nMonth: $month\nDay: $day\n";
            }
        }
    }
}

输出(用于您的样本数据):

File default.md:
Year: 2019
Month: 5
Day: 12
File default.md:
Year: 2019
Month: 12
Day: 22
File default.md:
Year: 2020
Month: 5
Day: 19

Demo on 3v4l.org

【讨论】:

    【解决方案2】:

    使用函数来处理令人困惑的嵌套方面应该会有很大帮助。我的示例绝不是一个可靠的解决方案。就个人而言,我可能会将函数放在一个类中并使其面向对象......但这绝对不是每种情况的正确解决方案。

    您必须适应这一点,但希望这个概念会有所帮助。

    function handleYear($year,$arrOfMonths){
         echo $year;
         foreach ($arrOfMonths as $month=>$arrOfDays){
             handleMonth($month,$arrOfDays);
         }
    }
    function handleMonth($month,$arrOfDays){
         echo $month;
         foreach ($arrOfDays as $dayOfMonth=>$listOfFiles){
             handleDay($dayOfMonth,$listOfFiles);
         }
    }
    
    //to get started
    foreach ($data as $year=>$arrOfMonths){
        echo $year;
        handleYear($year, $arrOfMonths);
    }
    

    您还可以修改子函数以接受父参数。就像handleMonth 也可以带入年份,然后handleYear 只是传递$year

    编辑:
    在看到您想要的输出之后......我建议将年份和月份传递给 handleDay 函数。那么handleDay 可能是这样的:

    function handleDay($day,$arrOfFiles,$year,$month) use (&$files){
        foreach ($arrOfFiles as $index=>$fileName){
            $file = ['year'=>$year,'month'=>$month,'day'=>$day];
            $files[] = $file; 
        }
    }
    

    如果我没记错的话,你需要在函数之外声明$files = [],然后再声明handleDay

    但是你只需要一个可以很容易处理的文件数组。

    就我个人而言,我可能会辛辛苦苦想出一个更清洁的解决方案(在这种情况下,我不喜欢 use 语句,我什至可能没有正确使用它)。如果它在课堂上,那么您可以使用$this-&gt;files 而不是use (&amp;$files)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-21
      • 2011-01-02
      • 2014-10-03
      • 2016-02-16
      • 2021-09-17
      • 1970-01-01
      相关资源
      最近更新 更多