商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 如何为患者发药记录按月份顺序补全缺失的零值项

如何为患者发药记录按月份顺序补全缺失的零值项

  发布于2026-07-05 阅读(0)

扫一扫,手机访问

本文介绍如何根据指定的最近7个月时间序列,自动向患者发药记录的 dispatch 数组中插入缺失月份的占位对象(quantity: 0),并按时间升序排序,确保数据完整且时序正确。

在医疗或药品分发系统里,一个很常见的场景是:需要按连续的时间维度(比如最近7个月)展示每个患者的用药量统计。但原始数据里的 dispatch 数组往往只记录了实际有发货的月份,中间空档直接跳过了。这会导致图表渲染出来断断续续,聚合计算也容易出错。下面要聊的,就是一个健壮又可直接复用的 PHP 解决方案——核心就三步:自动识别缺失月份 → 插入标准化占位项 → 按 period 升序重排

核心逻辑说明

  • 匹配依据:以 period 字符串(如 "2022-5")作为唯一键,把 months 列表里的元素和 dispatch 中已有的项逐一对比;
  • 补全规则:遍历 months 里的每个元素,如果它的 period 在 dispatch 中不存在,就生成一个新对象。month 数字从 period 里解析出来(避免硬编码月份值),year 直接取自 months,quantity 固定为 0;
  • 排序保障:每次插入新项后,立刻用 usort() 按 period 字典序升序排列("2021-12" 会排在 "2022–1" 前面),保证最终数组严格按时间顺序排列。

完整实现代码(PHP)

// 假设 $data 是原始响应 JSON 解码后的对象(含 records 数组)
// $monthsData 是包含最近7个月信息的 JSON 解码对象(含 months 数组)

foreach ($monthsData->months as $targetMonth) {
    foreach ($data->records as $record) {
        // 检查当前 record.dispatch 是否已存在该 period
        $exists = array_filter($record->dispatch, function($item) use ($targetMonth) {
            return $item->period === $targetMonth->period;
        });

        if (empty($exists)) {
            // 解析 period 获取 month 数字(如 "2022-5" → 5)
            $parsedDate = DateTime::createFromFormat('Y-m', $targetMonth->period);
            $monthNum = $parsedDate ? (int)$parsedDate->format('m') : (int)explode('-', $targetMonth->period)[1];

            // 构造新 dispatch 项
            $newDispatchItem = (object)[
                'month'   => $monthNum,
                'year'    => $targetMonth->year,
                'quantity'=> 0,
                'period'  => $targetMonth->period
            ];

            $record->dispatch[] = $newDispatchItem;

            // 按 period 升序重排(关键!保证时间连续性)
            usort($record->dispatch, function($a, $b) {
                return strcmp($a->period, $b->period);
            });
        }
    }
}

注意事项与最佳实践

  • 日期解析健壮性:用 DateTime::createFromFormat() 来解析 period,比 date('m', strtotime()) 更靠谱——可以避免 strtotime 对边界值(比如 "2021-13")的误判;
  • 性能优化:如果 dispatch 数组很大,可以先把现有 period 提取成一个关联数组($existingPeriods = array_column($record->dispatch, 'period');),然后用 in_array() 替代 array_filter(),时间复杂度降一个量级;
  • ⚠️ 数据一致性:尽量保证 months 数组本身按时间降序(比如从6月到12月)或升序排列,否则插入位置一开始可能看着有点怪——不过因为最后强制用 usort 排序了,最终结果不受影响;
  • ? 批量处理支持:这段代码天然支持多个患者(records 多条),外层循环直接搞定,不需要再套一层;
  • ? 扩展性提示:如果将来要兼容其他日期格式(比如 "YYYY/MM"),只需要改 period 的解析逻辑和比较条件,其他部分完全不动。

通过这个方案,每个患者的 dispatch 数组都能精准地包含目标时间段内的所有月份,缺失的月以 quantity: 0 显式补全。前端做可视化、同比环比分析、导出报表——底层数据基础扎实了,后面的事情就顺了。

本文转载于:https://www.php.cn/faq/2738530.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注