PHP - 仅在迭代之间发生变化时,循环遍历数组并打印输出值

Apologies if this has been asked but I can't find a solution that meets my needs.

I have an array in a PHP 7 application as follows:

$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'
    ],
    // ...
];

The output I want to achieve is like this:

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

America
    - G29
        -- FF3242
        -- FF48395043

Asia
    - G2000
        -- FF7

Essentially all it's doing is outputting the array in a structured format such that it shows the regulations_label followed by any corresponding groups_label and then any filters_label.

It's simple enough to loop through the entire array, e.g.

foreach ($data as $d) {
    echo $d['regulations_label'] . "
";
    echo ' - ' . $d['groups_label'] . "
";
    echo ' -- ' . $d['filters_label'] . "
";
}

However this introduces "duplicate" headings for regulations_label and groups_label because it's printing every single key. But I don't see how I can check if this has changed during the foreach statement because $d is always the current element.

I was attempting to do a check based on the previous array key:

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

The trouble is that this then just prints 1 groups_label so I'd end up with - for example:

Europe
- G1
America
...

It wouldn't get as far as "G2".

I can't help but think I'm going about this in a bizarre way. Can anyone advise a better solution?

Background info: The data I receive in $data isn't something I can modify because that format is required for the use case which is a feature in an application like this: jQuery load more data on scroll

you can use foreach and group by using regulations_label and groups_label

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

DEMO

In the simplest case you just need to add some if statements as you'd started to do, but you also have to make sure they only stop the relevant bit from printing - your version was suppressing the whole output, instead of just the top-level label:

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

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

Demo: https://3v4l.org/ihYVj

All you need to do is remember what you last processed and then adda couple of IF's

$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'] . "
";
        $last_reg = $reg['regulations_label'];
        $last_grp = NULL;
        $last_filter = NULL;
    }
    if ( $last_grp != $reg['groups_label']) {
        echo "\t - " . $reg['groups_label'] . "
";
        $last_grp = $reg['groups_label'];
    }
    echo "\t\t - " . $reg['filters_label'] . "
";
}

RESULT:

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