执行PHP数组的分组信息的最佳执行方式

时间:2015-09-24 15:03:24

标签: php laravel logic

我有一个由Laravel 5.1.x的数据库查询生成器生成的数组。

array:96 [▼
  0 => {#1256 ▼
    +"customer_id": 58
    +"city": "Rio de Janeiro"
    +"program_id": 3
    +"program": "PROGRAMA XPTO"
    +"subregion": "SUB-REGIÃO UM"
    +"mr_name": "2015/02"
    +"info_1": 8
    +"info_2": 9
    +"info_3": 239
    +"info_4": 10
    +"info_5": 295
    +"info_6": "12.3430962343096"
  }
  1 => {#1255 ▼
    +"customer_id": 58
    +"city": "Rio de Janeiro"
    +"program_id": 3
    +"program": "PROGRAMA XPTO"
    +"subregion": "SUB-REGIÃO UM"
    +"mr_name": "2015/03"
    +"info_1": 8
    +"info_2": 9
    +"info_3": 239
    +"info_4": 21
    +"info_5": 377
    +"info_6": "7.51145646543136"
  }
  2 => {#1254 ▼
    +"customer_id": 58
    +"city": "Rio de Janeiro"
    +"program_id": 3
    +"program": "PROGRAMA XPTO"
    +"subregion": "SUB-REGIÃO UM"
    +"mr_name": "2015/04"
    +"info_1": 8
    +"info_2": 9
    +"info_3": 239
    +"info_4": 19
    +"info_5": 607
    +"info_6": "13.3670997577626"
  }
  ...
]

问题:我想将这些信息分组。

array: [▼
    "customers" => { ▼
        +"Rio de Janeiro": array [▼
            +"programs": array [▼
                "PROGRAMA XPTO": array [▼
                    +"subregions": array [▼
                        "SUB-REGIÃO UM": array [▼
                            "months": array [▼
                                "2015/02": array [],
                                "2015/03": array [],
                                "2015/04": array [],
                                "2015/05": array [],
                                "2015/06": array [],
                                "2015/07": array [],
                                ...
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
  ...
]

使用纯PHP并迭代每个值我得到额外的5-10秒来渲染页面(下面的代码):

if (!empty($result)) {
    $city = $result[0]->city;
    $program = null;
    $subregion = null;
    $school = null;
    $class = null;

    $data['customers'] = [];

    foreach ($result as $r => $row) {
        if (isset($data[$row->city])) {
            continue;
        }

        $city = $row->city;
        $data['customers'][$city] = [];
        $data['customers'][$city]['customer_id'] = $row->customer_id;

        foreach ($result as $pid => $programs) {
            if ($city == $programs->city) {
                if (isset($data[$city]['programs'][$programs->program])) {
                    continue;
                }

                $program = $programs->program;

                $data['customers'][$city]['programs'][$program] = [
                    'program_id' => $programs->program_id,
                    'total_escolas' => false,
                    'total_turmas' => false,
                    'students' => false,
                    'subregions' => []
                ];

                foreach ($result as $subId => $subregions) {
                    if (($city == $subregions->city)
                        and ($program == $subregions->program)
                    ) {
                        $subregion = $subregions->subregion;
                        $data['customers'][$city]['programs'][$program]['subregions'][$subregions->subregion] = [
                            'months' => []
                        ];

                        foreach ($result as $mId => $months) {
                            if (($city == $months->city)
                                and ($program == $months->program)
                                and ($subregion == $months->subregion)
                                and !empty($data['customers'][$city]['programs'][$program]['subregions'][$subregion]['months'][$months->mr_name])
                            ) {
                                $mr_name = $months->mr_name;
                                $data['customers'][$city]['programs'][$program]['subregions'][$subregion]['months'][$mr_name] = [
                                    'info_1' => $months->info_1,
                                    'info_2' => $months->info_2,
                                    'info_3' => $months->info_3,
                                    'info_4' => $months->info_4,
                                    'info_5' => $months->info_5,
                                    'info_6' => $months->info_6
                                ];
                            }
                        }
                    }
                }
            }
        }
    }
}

Obs。:我的查询运行时间为137毫秒,页面加载速度为8秒。

  • 我做错了什么?
  • 还有另一种方法可以对这些数据进行分组吗?

如果您需要更多信息,请告诉我。

1 个答案:

答案 0 :(得分:1)

我看到它的方式,你有两个选择。关键是要对您的值进行排序,以便您可以对它们进行单次传递。在您的情况下,订单应该是:

  1. 城市
  2. 程序
  3. 分区域
  4. mr_name
  5. 选项1,在数据库

    在查询中添加4个orderBy()子句以实现该顺序。

    选项2,在php

    使用PHP的usort函数按所需顺序对值进行排序。

    最后

    在1遍中使用已排序的数组。迭代排序值时,使用变量记住上一个条目的城市,程序,子区域和mr_name。当前子区域与上一个子区域不同时,您知道您正在开始一个新的子区域,而最后一个子区域没有更多的元素。