英文:
How to merge arrays based on parent loop in PHP
问题
$mergedArray = [];
foreach ($rooms as $room) {
$roomInfo = [];
foreach ($paymentMethods as $payment) {
$paymentInfo = [];
foreach ($patients as $patient) {
if ($patient->roomCode == $room->roomCode && $patient->paymentCode == $payment->paymentCode) {
$paymentInfo[] = ['fullName' => $patient->fullName];
}
}
$roomInfo[$payment->paymentName] = $paymentInfo;
}
$mergedArray[$room->roomName] = $roomInfo;
}
英文:
I have a dataset of patients , room and payment method (which is an array of objects). Those 3 arrays looks like this:
$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
],
];
What I'm expecting to achieve is to merge the patient array to room and payment method array to get their respective names based on the parent loop.
The expected array will kind of looks like this:
$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']
],
],
]
];
I've tried using loop this way:
$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];
}
}
}
}
Above code gave me Illegal offset type
error. Any ideas how to achieve this?
答案1
得分: 3
在你的代码中,$room
是一个数组,并尝试将其用作键 ($mergedArray[$room]
)。这是无法正常工作的原因,也是你收到错误消息的原因。
如果你首先使用关联数组按其相关代码键入房间名称和付款方式名称,将更有效(并且更优雅):
$roomMap = array_column($rooms, "roomName", "roomCode");
$paymentMap = array_column($paymentMethods, "paymentName", "paymentCode");
一旦你有了这个,你只需要一个循环:
foreach($patients as $patient) {
$merged[$roomMap[$patient->roomCode]][$paymentMap[$patient->paymentCode]][] = ["fullName" => $patient->fullName];
}
现在 $merged
是:
[
'Room 1' => [
'Payment 1' => [
['fullName' => 'Patient A'],
['fullName' => 'Patient B'],
],
'Payment 3' => [
['fullName' => 'Patient D'],
],
],
'Room 2' => [
'Payment 1' => [
['fullName' => 'Patient C'],
],
],
'Room 3' => [
'Payment 3' => [
['fullName' => 'Patient E'],
],
],
]
这样,你在结果中就不会得到那些空的付款槽。如果你真的也想要这些空槽,那么首先用空数组初始化目标结构:
$merged = [];
foreach($roomMap as $roomName) {
foreach($paymentMap as $paymentName) {
$merged[$roomName][$paymentName] = [];
}
}
foreach($patients as $patient) {
$merged[$roomMap[$patient->roomCode]][$paymentMap[$patient->paymentCode]][] = ["fullName" => $patient->fullName];
}
如果房间和支付的组合数少于居住在设施中的患者数量,这仍然更有效。
英文:
In your code $room
is an array, and there is an attempt to use it as a key ($mergedArray[$room]
). That cannot work and is the reason for the error message you get.
It will be more efficient (and elegant) if you first key your room names and payment method names by their relevant codes in associative arrays:
$roomMap = array_column($rooms, "roomName", "roomCode");
$paymentMap = array_column($paymentMethods, "paymentName", "paymentCode");
Once you have that, you only need one loop:
foreach($patients as $patient) {
$merged[$roomMap[$patient->roomCode]][$paymentMap[$patient->paymentCode]][]
= ["fullName" => $patient->fullName];
}
Now $merged
is:
[
'Room 1' => [
'Payment 1' => [
['fullName' => 'Patient A'],
['fullName' => 'Patient B'],
],
'Payment 3' => [
['fullName' => 'Patient D'],
],
],
'Room 2' => [
'Payment 1' => [
['fullName' => 'Patient C'],
],
],
'Room 3' => [
'Payment 3' => [
['fullName' => 'Patient E'],
],
],
]
This way you don't get those empty payment slots in your result. If you really want those empty slots as well, then first initialise the targeted structure with empty arrays:
$merged = [];
foreach($roomMap as $roomName) {
foreach($paymentMap as $paymentName) {
$merged[$roomName][$paymentName] = [];
}
}
foreach($patients as $patient) {
$merged[$roomMap[$patient->roomCode]][$paymentMap[$patient->paymentCode]][]
= ["fullName" => $patient->fullName];
}
This will still be more efficient if the number of combinations of rooms and payments is less than the number of patients residing in the facility.
答案2
得分: 1
试一下这个:
编辑:通过添加if语句更正了解决方案。
$mergedArray = [];
foreach ($rooms as $room) {
// 为收集付款创建空数组
$mergedArray[$room["roomName"]] = [];
foreach ($paymentMethods as $payment) {
// 为稍后填充患者创建空数组
$mergedArray[$room["roomName"]][$payment["paymentName"]] = [];
foreach ($patients as $patient) {
// 推送患者,因为键'fullName'是重复的
// 不能使用相同的键添加另一个键值对。
if ($patient["roomCode"] == $room["roomCode"] && $patient["paymentCode"] == $payment["paymentCode"]) {
array_push(
$mergedArray[$room["roomName"]][$payment["paymentName"]],
["fullName" => $patient["fullName"]]);
}
}
}
}
print_r($mergedArray);
英文:
Try this one:
Edit: solution corrected by adding if statement.
$mergedArray = [];
foreach ($rooms as $room) {
//create empty array for collecting payments
$mergedArray[$room["roomName"]] = [];
foreach ($paymentMethods as $payment) {
//create empty array for filling it with patients later.
$mergedArray[$room["roomName"]][$payment["paymentName"]] = [];
foreach ($patients as $patient) {
//push patients because key 'fullName' is duplicate
//you cant add another key-value pair with the same key.
if ($patient["roomCode"] == $room["roomCode"] && $patient["paymentCode"] == $payment["paymentCode"]) {
array_push(
$mergedArray[$room["roomName"]][$payment["paymentName"]],
["fullName" => $patient["fullName"]]);
}
}
}
}
print_r($mergedArray);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论