今天遇到了一个问题记录一下,遇到同样困难的朋友可参考一下,现有一个数组A,另外有一个数组B,大体结构如下.
数组内容
大体如下,简单记一下,实际情况比这多得多.根据'serial_number'来组装数组,A中的'serial_number'是唯一值.
$A = [
[
'id' => '12',
'serial_number' => 'Y2011020001',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
],
[
'id' => '13',
'serial_number' => 'Y2011020002',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
],
[
'id' => '14',
'serial_number' => 'Y2011020003',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
],
[
'id' => '15',
'serial_number' => 'Y2011020004',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
],
];
$B = [
[
'id' => '112',
'serial_number' => 'Y2011020001',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
[
'id' => '113',
'serial_number' => 'Y2011020001',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
[
'id' => '114',
'serial_number' => 'Y2011020001',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
[
'id' => '115',
'serial_number' => 'Y2011020004',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
];
需求
寻找B数组所有'serial_number'与A数组的'serial_number'相同的,并把数据插进去,以上面为例,最终效果如下:
$A = [
[
'id' => '12',
'serial_number' => 'Y2011020001',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
'child' => [
[
'id' => '112',
'serial_number' => 'Y2011020001',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
[
'id' => '113',
'serial_number' => 'Y2011020001',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
[
'id' => '114',
'serial_number' => 'Y2011020001',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
],
],
[
'id' => '13',
'serial_number' => 'Y2011020002',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
'child' => [],
],
[
'id' => '14',
'serial_number' => 'Y2011020003',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
'child' => [],
],
[
'id' => '15',
'serial_number' => 'Y2011020004',
'finish' => '2020-11-02 13:00:00',
'ratio_number' => 'S35X-R3',
'child' => [
[
'id' => '115',
'serial_number' => 'Y2011020004',
'card' => '2020-11-02 13:00:00',
'st' => 'EXSSEX',
],
],
],
];
思路
处理数组,最先想到的肯定是foreach来处理,少的话肯定没问题,但是实际中A数组与B数组各有1000个元素,总循环就要1000*1000次循环了,如果A和B各有1万,就要1亿次循环,而且直接用foreach感觉不爽,想做一些骚操作,就想别的处理方法.
首先肯定要先foreach A的,然后带着A的值去找B.
B中有重复的,并且还要取出来组成数组装进对应的A中.网络上找了一些资料,就二分法的启发有点作用.
B中的serial_number虽然有重复,但是按顺序排列的,最开始我想的是可以生成一种类似于地图映射这种减少循环范围.
先count出有多少元素,然后在B数组的5/1, 5/2, 5/3, 5/4, 5/5的位置取'serial_number'值,然后forea A的时候,判断A的'serial_number'值大体在数组的那个位置,直接for B的那个区间去拼装A.
再后来我想到,用array_search()方法,直接定位到开始key的位置往后面循环,到不同的元素就break出来.
最后我用了array_keys方法,这个可以返回指定值在数组中的所有key.所以直接提出来B的serial_number,然后找到键名直接装进去.实现效果如下
实现
//直接取出B中所有的serial_number,它的key是和原数组的key对应的
$b_serial_array = array_column($B, 'serial_number');
foreach ($A as $key => $value) {
$A[$key]['child'] = [];
//获取当前serial_number在B数组中所有的key.
$key_array = array_keys($b_serial_array, $value['serial_number']);
//如果未获取到就说明没有,进行下次循环
if (empty($key_array)) continue;
//不为空就循环组装进去A数组
foreach ($key_array as $k) {
$A[$key]['child'][] = $B[$k];
}
}
return $A;
至此结束.