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

PHP多维数组赋值前的邻居ID条件比较问题求助

解决方案:基于已分配ID的邻避规则实现ID分配

我来帮你一步步实现这个逻辑,核心是先从多维数组里提取最新已分配的ID,再匹配它的邻避列表,最后筛选出符合条件的待分配ID,避免陷入无限跳过的循环。

步骤拆解

  1. 提取$schedule中最新已分配的ID:遍历整个多维数组,收集所有非空的ID,取最后一个就是最近分配的那个。
  2. 构建ID到邻避列表的映射:把$idAndNeighbour转换成更易查询的结构,方便快速获取某个ID对应的所有邻避ID。
  3. 筛选符合条件的待分配ID:遍历待分配ID队列,找到第一个不在邻避列表里的ID,这就解决了“仅在$idAndNeighbour内比较导致持续跳过”的问题。
  4. 分配ID到$schedule:把选中的ID填充到$schedule的第一个空位置。

完整代码实现

<?php
// 原始数组定义
$schedule = array(
    0 => array( // day 0
        0 => array( // session 1
            0 => array( // room 405
                0 => "5" // id from arr2
            ),
            1 => array( // room 406
                0 => "7"
            ),
            2 => array( // room 407
                0 => ""
            ),
            3 => array( // room 408
                0 => ""
            )
        )
    )
);

$idAndNeighbour = array(
    0 => array(
        'id'=>5,
        'neighbour1' => 4,
        'neighbour5' => 22,
    ),
    1 => array(
        'id'=>7,
        'neighbour1' => 9,
        'neighbour5' => 24,
    ),
    2 => array(
        'id'=>9,
        'neighbour1' => 7,
        'neighbour5' => 23,
    ),
    3 => array(
        'id'=>14,
        'neighbour1' => 8,
        'neighbour5' => 26,
    )
);

// 待分配ID队列,按优先级排序
$pendingIds = [9, 14];

// 1. 收集所有已分配的非空ID
$assignedIds = [];
array_walk_recursive($schedule, function($value) use (&$assignedIds) {
    if (!empty($value)) {
        $assignedIds[] = (int)$value;
    }
});

// 2. 构建ID到邻避列表的映射
$idToNeighbours = [];
foreach ($idAndNeighbour as $item) {
    $id = $item['id'];
    // 提取所有以neighbour开头的字段值
    $neighbours = array_filter($item, function($key) {
        return str_starts_with($key, 'neighbour');
    }, ARRAY_FILTER_USE_KEY);
    $idToNeighbours[$id] = array_values($neighbours);
}

// 3. 筛选符合条件的待分配ID
$selectedId = null;
if (empty($assignedIds)) {
    // 初始无已分配ID,直接取第一个待分配ID
    $selectedId = reset($pendingIds);
} else {
    $lastAssignedId = end($assignedIds);
    $forbiddenIds = $idToNeighbours[$lastAssignedId] ?? [];
    
    foreach ($pendingIds as $id) {
        if (!in_array($id, $forbiddenIds)) {
            $selectedId = $id;
            break;
        }
    }
}

// 处理所有待分配ID都被禁止的边界情况
if ($selectedId === null) {
    throw new Exception("All pending IDs are forbidden to assign next.");
}

// 4. 将选中的ID分配到$schedule的第一个空位置
$assigned = false;
array_walk_recursive($schedule, function(&$value) use ($selectedId, &$assigned) {
    if (empty($value) && !$assigned) {
        $value = (string)$selectedId;
        $assigned = true;
    }
});

// 输出结果
print_r($schedule);
?>

代码说明

  • 多维数组遍历:用array_walk_recursive可以轻松遍历嵌套的$schedule数组,不用写多层循环,简洁高效。
  • 映射构建:把$idAndNeighbour转换成ID => [neighbour1, neighbour5...]的结构,查询邻避列表的效率更高,也更易维护。
  • 边界处理:考虑了初始无已分配ID和所有待分配ID都被禁止的情况,避免程序崩溃或陷入死循环。
  • 分配逻辑:找到$schedule中第一个空位置填充选中的ID,确保分配位置的合理性。

运行这段代码后,$schedule中room407的位置会被填充为14——因为9是最后已分配ID7的邻避ID,所以被跳过,改用下一个符合条件的ID14,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:42:37