PHP-仅当数组在迭代之间更改时,才循环遍历数组并打印出值

PHP-仅当数组在迭代之间更改时,才循环遍历数组并打印出值,php,arrays,Php,Arrays,如果有人问我这个问题,我会道歉,但我找不到满足我需求的解决方案 我在PHP 7应用程序中有一个数组,如下所示: $data = [ 0 => [ 'regulations_label' => 'Europe', 'groups_label' => 'G1', 'filters_label' => 'FF1' ], 1 => [ 'regulations_label' =>

如果有人问我这个问题,我会道歉,但我找不到满足我需求的解决方案

我在PHP 7应用程序中有一个数组,如下所示:

$data = [
    0 => [
        'regulations_label' => 'Europe',
        'groups_label' => 'G1',
        'filters_label' => 'FF1'
    ],
    1 => [
        'regulations_label' => 'Europe',
        'groups_label' => 'G1',
        'filters_label' => 'FF900'
    ],
    2 => [
        'regulations_label' => 'Europe',
        'groups_label' => 'G1',
        'filters_label' => 'FF324234'
    ],
    3 => [
        'regulations_label' => 'Europe',
        'groups_label' => 'G2',
        'filters_label' => 'FF23942'
    ],
    4 => [
        'regulations_label' => 'America',
        'groups_label' => 'G29',
        'filters_label' => 'FF3242'
    ],
    5 => [
        'regulations_label' => 'America',
        'groups_label' => 'G29',
        'filters_label' => 'FF78978'
    ],
    6 => [
        'regulations_label' => 'America',
        'groups_label' => 'G29',
        'filters_label' => 'FF48395043'
    ],
    7 => [
        'regulations_label' => 'Asia',
        'groups_label' => 'G2000',
        'filters_label' => 'FF7'
    ],
    // ...
];
我想要实现的输出如下:

Europe
    - G1
        -- FF1
        -- FF900
    - G2
        -- FF23942

America
    - G29
        -- FF3242
        -- FF48395043

Asia
    - G2000
        -- FF7
基本上,它所做的就是以结构化格式输出数组,这样它就会显示
规则\u标签
,然后是任何相应的
组\u标签
,然后是任何
过滤器\u标签

它非常简单,可以在整个阵列中循环,例如

foreach ($data as $d) {
    echo $d['regulations_label'] . "\n";
    echo ' - ' . $d['groups_label'] . "\n";
    echo ' -- ' . $d['filters_label'] . "\n";
}
但是,这会为
regulations\u label
groups\u label
引入“重复”标题,因为它会打印每个键。但是我不知道如何在
foreach
语句中检查这是否已更改,因为
$d
始终是当前元素

我正试图基于上一个数组键执行检查:

foreach ($data as $key => $d) {
   if ($data[$key-1]['regulations_label'] !== $d['regulations_label']) {
       echo $d['regulations_label'] . "\n";
       echo "-" . $d['groups_label'] . "\n";
   }
}
问题是,这只会打印1个
组\u标签
,因此我最终会得到-例如:

Europe
- G1
America
...
它不会达到“G2”

我忍不住想我是在用一种奇怪的方式来处理这件事。有人能提出更好的解决方案吗


背景信息:我在
$data
中收到的数据不是我可以修改的,因为用例需要这种格式,而用例是这样一个应用程序中的一个特性:

您可以使用
foreach
并使用
规则\u标签和
组\u标签进行分组

$group = [];
foreach($data as $v){
  $group[$v['regulations_label']][$v['groups_label']][] = $v['filters_label'];
}

在最简单的情况下,您只需要像开始那样添加一些
if
语句,但您还必须确保它们只停止打印相关位-您的版本正在抑制整个输出,而不仅仅是顶级标签:

foreach ($data as $key => $d) {
   if ($key > 0) {
       if ($data[$key-1]['regulations_label'] !== $d['regulations_label']) {
           echo $d['regulations_label'] . "\n";   

       }
       if ($data[$key-1]['groups_label'] !== $d['groups_label']) {
           echo "-" . $d['groups_label'] . "\n";
       }
   }
   else
   {
       //special case to deal with first row where $key-1 doesn't exist
       echo $d['regulations_label'] . "\n";   
       echo "-" . $d['groups_label'] . "\n";
   }
   echo ' -- ' . $d['filters_label'] . "\n";
}

演示:

您需要做的就是记住上次处理的内容,然后添加几个IF

$data = [
    0 => ['regulations_label' => 'Europe','groups_label' => 'G1','filters_label' => 'FF1'],
    1 => ['regulations_label' => 'Europe','groups_label' => 'G1','filters_label' => 'FF900'],
    2 => ['regulations_label' => 'Europe','groups_label' => 'G1','filters_label' => 'FF324234'],
    3 => ['regulations_label' => 'Europe','groups_label' => 'G2','filters_label' => 'FF23942'],
    4 => ['regulations_label' => 'America','groups_label' => 'G29','filters_label' => 'FF3242'],
    5 => ['regulations_label' => 'America','groups_label' => 'G29','filters_label' => 'FF78978'],
    6 => ['regulations_label' => 'America','groups_label' => 'G29','filters_label' => 'FF48395043'],
    7 => ['regulations_label' => 'Asia','groups_label' => 'G2000','filters_label' => 'FF7']
];

$last_reg = NULL;
$last_grp = NULL;

foreach ($data as $reg) {

    if ( $last_reg != $reg['regulations_label']) {
        echo $reg['regulations_label'] . "\n";
        $last_reg = $reg['regulations_label'];
        $last_grp = NULL;
        $last_filter = NULL;
    }
    if ( $last_grp != $reg['groups_label']) {
        echo "\t - " . $reg['groups_label'] . "\n";
        $last_grp = $reg['groups_label'];
    }
    echo "\t\t - " . $reg['filters_label'] . "\n";
}
结果:

Europe
     - G1
         - FF1
         - FF900
         - FF324234
     - G2
         - FF23942
America
     - G29
         - FF3242
         - FF78978
         - FF48395043
Asia
     - G2000
         - FF7

这是一个很好的解决方案,因为它使用
$group
数组的内存开销,导致的问题比公认的答案要少。它发出了一个
通知:未定义的偏移量:-1
错误。@Andy对此表示抱歉。。。请参阅上面更新的演示和代码示例。这只是第一行的问题,因为显然当$key为0时,$key-1处没有数组索引!