You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

键值相同时如何计算两个多维数组的差异?已尝试多方案未解决

解决多维数组基于键值匹配的差异对比问题

嘿,我懂你现在的困扰——多维数组的差异对比本来就比一维数组麻烦,尤其是还要严格基于键值匹配的情况。我之前做项目的时候也碰到过几乎一模一样的场景,给你分享个针对性的解决方案,应该能解决你的问题。

先明确场景和示例数组

首先咱们把你提到的数组补全,方便测试:

// 数据库里的原始数据(DbData)
$dbData = [
    "phase-5[]" => [
        '1' => "Admin Phase 1 Task 1",
        '2' => "Admin Phase 1 Task 2"
    ],
    "phase-6[]" => [
        '1' => "Admin Phase 2 Task 1",
        '2' => "Admin Phase 2 Task 2"
    ],
    "phase-7[]" => [
        '1' => "Admin Phase 3 Task 1"
    ]
];

// 前端传过来的新数据(ajaxData)
$ajaxData = [
    "phase-5[]" => [
        '1' => "Admin Phase 1 Task 1 (Updated)", // 内容修改
        '2' => "Admin Phase 1 Task 2"
    ],
    "phase-6[]" => [
        '1' => "Admin Phase 2 Task 1",
        '3' => "Admin Phase 2 Task 3" // 新增任务
    ],
    "phase-8[]" => [ // 新增整个phase
        '1' => "Admin Phase 4 Task 1"
    ]
];

核心对比函数

这个函数会分层处理:先对比外层的phase键,再对比每个phase下的任务键值对,最后返回一个包含新增、删除、修改三类差异的数组:

function compareMultiArrays($original, $new) {
    $differences = [
        'added' => [],
        'removed' => [],
        'modified' => []
    ];

    // 获取所有外层键的并集,确保不会漏掉任何一个phase
    $allPhaseKeys = array_unique(array_merge(array_keys($original), array_keys($new)));

    foreach ($allPhaseKeys as $phaseKey) {
        // 情况1:该phase只在新数组里(新增的phase)
        if (!isset($original[$phaseKey]) && isset($new[$phaseKey])) {
            $differences['added'][$phaseKey] = $new[$phaseKey];
            continue;
        }

        // 情况2:该phase只在原数组里(删除的phase)
        if (isset($original[$phaseKey]) && !isset($new[$phaseKey])) {
            $differences['removed'][$phaseKey] = $original[$phaseKey];
            continue;
        }

        // 情况3:两边都有这个phase,对比内层任务
        $originalTasks = $original[$phaseKey];
        $newTasks = $new[$phaseKey];
        $allTaskKeys = array_unique(array_merge(array_keys($originalTasks), array_keys($newTasks)));

        foreach ($allTaskKeys as $taskKey) {
            // 任务只在新数组里(新增任务)
            if (!isset($originalTasks[$taskKey]) && isset($newTasks[$taskKey])) {
                $differences['added'][$phaseKey][$taskKey] = $newTasks[$taskKey];
            }
            // 任务只在原数组里(删除任务)
            elseif (isset($originalTasks[$taskKey]) && !isset($newTasks[$taskKey])) {
                $differences['removed'][$phaseKey][$taskKey] = $originalTasks[$taskKey];
            }
            // 任务键存在但内容不同(修改任务)
            elseif ($originalTasks[$taskKey] !== $newTasks[$taskKey]) {
                $differences['modified'][$phaseKey][$taskKey] = [
                    'old' => $originalTasks[$taskKey],
                    'new' => $newTasks[$taskKey]
                ];
            }
        }
    }

    // 过滤掉空的分类,让结果更干净
    foreach ($differences as $key => $value) {
        if (empty($value)) {
            unset($differences[$key]);
        }
    }

    return $differences;
}

测试函数并查看结果

调用函数然后打印结果:

$diff = compareMultiArrays($dbData, $ajaxData);
print_r($diff);

输出结果会是:

Array
(
    [added] => Array
        (
            [phase-6[]] => Array
                (
                    [3] => Admin Phase 2 Task 3
                )
            [phase-8[]] => Array
                (
                    [1] => Admin Phase 4 Task 1
                )
        )
    [removed] => Array
        (
            [phase-7[]] => Array
                (
                    [1] => Admin Phase 3 Task 1
                )
            [phase-6[]] => Array
                (
                    [2] => Admin Phase 2 Task 2
                )
        )
    [modified] => Array
        (
            [phase-5[]] => Array
                (
                    [1] => Array
                        (
                            [old] => Admin Phase 1 Task 1
                            [new] => Admin Phase 1 Task 1 (Updated)
                        )
                )
        )
)

关键注意事项

  • 确保外层的phase键完全一致(比如你示例里的phase-5[],括号不能少,大小写也要匹配),否则会被当成不同的phase
  • 如果你的数组层级更深,可以把内层的对比逻辑改成递归调用,这个函数很容易扩展
  • 函数里用了!==来对比值,会严格区分类型(比如数字和字符串的1会被当成不同),如果不需要严格类型对比,可以改成!=

内容的提问来源于stack exchange,提问作者WebRence

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:01:57