如何依据唯一名称分组,对numbers字段执行implode合并操作?
问题:合并同名字段的
numbers值 现有数据库表结构
| id | name | numbers |
|---|---|---|
| 1 | Kathy | 5 |
| 2 | Kathy | 15 |
| 3 | Kathy | 25 |
| 4 | William | 5 |
| 5 | William | 10 |
期望处理后结构
| id | name | numbers |
|---|---|---|
| 1 | Kathy | 5.15.25 |
| 2 | William | 5.10 |
现有代码及问题
用户编写的PHP代码:
$arr_name = []; $arr_numbers = []; $arr_implode = []; $data= MyDatabase::all(); foreach ($data as $data) { if ($data->name == $data->name) { $arr_numbers [] = $data->numbers; } else { $arr_numbers [] = $data->numbers; } $arr_implode[$data->name] = implode('.', $arr_numbers); }
执行dd($arr_implode);得到的错误结果:
array:2 [▼ "Kathy" => "5.15.25" "William" => "5.15.25.5.10" ]
问题原因
原代码中$arr_numbers是全局数组,所有记录的numbers都会被追加到同一个数组里,导致切换到William时,数组里还保留着Kathy的数值,最终合并出错误的字符串。另外代码里的if判断完全无效($data->name == $data->name永远为真)。
修改后的代码
第一步:按name分组合并numbers
$arr_implode = []; $data = MyDatabase::all(); foreach ($data as $item) { // 以name为键,为每个name单独维护对应的numbers数组 $arr_implode[$item->name][] = $item->numbers; } // 将每个name对应的数组转为用点连接的字符串 foreach ($arr_implode as $name => $numbersArr) { $arr_implode[$name] = implode('.', $numbersArr); }
执行dd($arr_implode);会得到正确的分组结果:
array:2 [▼ "Kathy" => "5.15.25" "William" => "5.10" ]
第二步(可选):生成带自增id的最终结构
如果需要和期望表结构一致的带id的数组,可以再做如下处理:
$result = []; $currentId = 1; foreach ($arr_implode as $name => $numbersStr) { $result[] = [ 'id' => $currentId++, 'name' => $name, 'numbers' => $numbersStr ]; }
此时$result的结构就完全匹配期望的表结构了。
内容的提问来源于stack exchange,提问作者NeedHalp
相关产品推荐
相关产品推荐

