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

时间:2019-06-19 13:20:15

标签: php arrays

很抱歉,如果有人提出这个要求,但我找不到符合我需要的解决方案。

我在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

本质上来说,它所做的就是以结构化格式输出数组,以使其显示regulations_label,然后显示任何对应的groups_label,然后显示任何filters_label

它很容易遍历整个数组,例如

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

但是,这会为regulations_labelgroups_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 groups_label,所以我最终得到-例如:

Europe
- G1
America
...

它不会达到“ G2”。

我忍不住想,我正在以一种怪异的方式来解决这个问题。谁能建议更好的解决方案?

背景信息:我无法修改$data中接收到的数据,因为用例需要这种格式,而这种用例是诸如此类的应用程序中的功能:jQuery load more data on scroll

3 个答案:

答案 0 :(得分:7)

您可以使用foreach并通过使用regulations_labelgroups_label进行分组

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

DEMO

答案 1 :(得分:2)

在最简单的情况下,您只需要在开始时添加一些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";
}

演示:https://3v4l.org/ihYVj

答案 2 :(得分:0)

您需要做的就是记住上一次处理的内容,然后添加几个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