PHP中如何基于父循环合并患者、房间与支付方式数组?
问题:按房间名称、支付方式名称分组整合患者数组
原始数据结构
房间数组
$rooms = [ (object) [ 'roomCode' => 1, 'roomName' => 'Room 1' ], (object) [ 'roomCode' => 2, 'roomName' => 'Room 2' ], (object) [ 'roomCode' => 3, 'roomName' => 'Room 3' ], ];
支付方式数组
$paymentMethods = [ (object) [ 'paymentCode' => 1, 'paymentName' => 'Payment 1' ], (object) [ 'paymentCode' => 2, 'paymentName' => 'Payment 2' ], (object) [ 'paymentCode' => 3, 'paymentName' => 'Payment 3' ], ];
患者数组
$patients = [ (object) [ 'fullName' => 'Patient A', 'roomCode' => 1, 'paymentCode' => 1 ], (object) [ 'fullName' => 'Patient B', 'roomCode' => 1, 'paymentCode' => 1 ], (object) [ 'fullName' => 'Patient C', 'roomCode' => 2, 'paymentCode' => 1 ], (object) [ 'fullName' => 'Patient D', 'roomCode' => 1, 'paymentCode' => 3 ], (object) [ 'fullName' => 'Patient E', 'roomCode' => 3, 'paymentCode' => 3 ], ];
期望的合并结构
$mergedArray = [ [ 'Room 1' => [ 'Payment 1' => [ 0 => ['fullName' => 'Patient A'], 1 => ['fullName' => 'Patient B'] ], 'Payment 2' => [], 'Payment 3' => [ 0 => ['fullName' => 'Patient D'], ] ], 'Room 2' => [ 'Payment 1' => [ 0 => ['fullName' => 'Patient C'] ], 'Payment 2' => [], 'Payment 3' => [], ], 'Room 3' => [ 'Payment 1' => [], 'Payment 2' => [], 'Payment 3' => [ 0 => ['fullName' => 'Patient E'] ], ], ] ];
尝试的代码及错误
尝试的代码:
$mergedArray = []; foreach ($rooms as $room) { $mergedArray[] = $room; foreach ($paymentMethods as $payment) { $mergedArray[$room] = $payment; foreach ($patients as $patient) { if ($patient->roomCode == $room->roomCode && $patient->paymentCode == $payment->paymentCode) { $mergedArray[$payment] = ['fullName' => $patient->fullName]; } } } }
运行后出现 Illegal offset type 错误。
错误原因分析
Illegal offset type 错误是因为直接用对象($room、$payment)作为数组的键,而PHP数组的键只能是整数(int)或字符串(string)类型,不能是对象。
正确实现代码
要实现预期结构,需要先初始化房间和支付方式的空结构,再将患者分配到对应分组中:
基础实现版本
$mergedArray = []; // 第一步:初始化房间和对应的支付方式空结构 foreach ($rooms as $room) { $roomName = $room->roomName; $mergedArray[0][$roomName] = []; foreach ($paymentMethods as $payment) { $paymentName = $payment->paymentName; $mergedArray[0][$roomName][$paymentName] = []; } } // 第二步:将患者分配到对应的分组 foreach ($patients as $patient) { // 根据roomCode匹配房间名称 $matchedRoom = array_filter($rooms, fn($r) => $r->roomCode == $patient->roomCode); $roomName = reset($matchedRoom)->roomName; // 根据paymentCode匹配支付方式名称 $matchedPayment = array_filter($paymentMethods, fn($p) => $p->paymentCode == $patient->paymentCode); $paymentName = reset($matchedPayment)->paymentName; // 添加患者信息到对应分组 $mergedArray[0][$roomName][$paymentName][] = ['fullName' => $patient->fullName]; } print_r($mergedArray);
性能优化版本
如果数据量较大,建议先将房间和支付方式转换成code为键的映射数组,减少重复查找的开销:
$mergedArray = []; // 预生成房间映射:roomCode => roomName $roomMap = []; foreach ($rooms as $room) { $roomMap[$room->roomCode] = $room->roomName; } // 预生成支付方式映射:paymentCode => paymentName $paymentMap = []; foreach ($paymentMethods as $payment) { $paymentMap[$payment->paymentCode] = $payment->paymentName; } // 初始化结构 foreach ($roomMap as $roomName) { $mergedArray[0][$roomName] = []; foreach ($paymentMap as $paymentName) { $mergedArray[0][$roomName][$paymentName] = []; } } // 分配患者到对应分组 foreach ($patients as $patient) { $roomName = $roomMap[$patient->roomCode]; $paymentName = $paymentMap[$patient->paymentCode]; $mergedArray[0][$roomName][$paymentName][] = ['fullName' => $patient->fullName]; } print_r($mergedArray);
内容的提问来源于stack exchange,提问作者Rizky Irmawan
相关产品推荐
相关产品推荐

