标题:PHP 中基于共享列合并两个二维数组并填充默认值的完整教程

本文详解如何在 php 中按日期等共享键列合并两个二维数组,自动补全缺失项并用默认值(如 0)填充空缺字段,适用于报表对齐、数据对比等场景。

在实际开发中,我们常需将两组结构相似但时间范围或记录不完全重叠的二维数组(如“当日新增工单”和“当日关闭工单”)按公共键(如日期)对齐合并,生成一份完整的时间序列汇总表。此时不仅需要匹配共有的键,还必须为某一数组中缺失的键提供默认值(如 0),确保结果数组覆盖全部时间点且结构统一。

以下是一个高效、简洁且可扩展的解决方案,无需嵌套循环,避免了原始代码中仅遍历 $openTicket 导致 $closeTicket 独有日期丢失的问题:

✅ 核心思路三步法

  1. 提取并去重所有日期:使用 array_column() 提取两数组的第 0 列(日期),再用 array_merge() 合并 + array_unique() 去重,获得完整时间轴;
  2. 构建键值映射索引:再次调用 array_column($array, $valueIndex, $keyIndex),将每个数组转为 ['date' => value] 形式的关联数组,大幅提升查找效率;
  3. 统一填充输出:遍历完整日期列表,利用空合并运算符 ?? 0 安全取值——若某日期在 $open 或 $closed 中不存在,则自动回退为 0。

? 完整示例代码

// 示例数据(注意变量名修正:$closedTicket 而非 $closeTicket,提升可读性)
$openTicket = [
    ['2025-01-19', 6],
    ['2025-01-20', 1],
    ['2025-01-21', 1],
    ['2025-01-22', 2],
];

$closedTicket = [
    ['2025-01-17', 6],
    ['2025-01-18', 1],
    ['2025-01-21', 1],
    ['2025-01-23', 2],
];

// 步骤 1:获取全部唯一日期
$dates = array_unique(array_merge(
    array_column($openTicket, 0),
    array_column($closedTicket, 0)
));
sort($dates); // 可选:按时间升序排列结果

// 步骤 2:构建以日期为键的快速查找表
$openByDate   = array_column($openTicket, 1, 0);   // ['2025-01-19' => 6, ...]
$closedByDate = array_column($closedTicket, 1, 0); // ['2025-01-17' => 6, ...]

// 步骤 3:生成最终对齐数组
$finalArray = [];
foreach ($dates as $date) {
    $finalArray[] = [
        $date,
        $openByDate[$date] ?? 0,      // 缺失则为 0
        $closedByDate[$date] ?? 0    // 缺失则为 0
    ];
}

print_r($finalArray);

⚠️ 注意事项与最佳实践

  • 键冲突安全:array_column($arr, 1, 0) 要求第 0 列值全局唯一;若存在重复日期(如同一天多条记录),后者将覆盖前者。如需聚合(如求和),应先用 array_reduce() 或 foreach 预处理。
  • 类型一致性:确保两数组中作为键的列(如日期)数据类型一致(均为字符串或均为 DateTime 对象),否则 ?? 运算可能因隐式转换失败。
  • 性能优势:该方案时间复杂度为 O(n + m),远优于原始嵌套循环的 O(n × m),尤其适合千级以上数据。
  • 扩展性提示:如需支持更多数组(如“待处理”、“延期”),只需增加 array_merge() 和 array_column() 调用,并在 foreach 中扩展字段即可。

通过此方法,你不仅能精准实现“左+右外连接”式合并,还能保持代码简洁、健壮且易于维护,是 PHP 数组数据对齐任务的标准实践。