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

如何在PHP秘密圣诞老人程序中实现黑名单排除功能?

秘密圣诞老人抽签程序:添加黑名单排除逻辑

问题分析

现有代码存在语法错误(如array_diff的调用方式)、随机索引取值逻辑错误,且核心的黑名单排除逻辑未有效融入配对流程,导致无法实现预期的避嫌效果。

修正后的代码

<?php
$result = [];
// 复制收件人数组,避免直接修改原数据
$availableRecipients = $recipient;

foreach ($supplier as $sup) {
    // 过滤当前送礼人可选择的收件人:排除自己、黑名单对象,且处于可选列表中
    $validRecipients = array_filter($availableRecipients, function($recip) use ($sup) {
        // 排除自己(假设用姓氏作为唯一标识,可根据实际字段调整)
        if ($recip['surname'] === $sup['surname']) {
            return false;
        }
        // 排除黑名单中的对象(确保$sup['blacklist']是存储收件人标识的数组)
        if (in_array($recip['surname'], $sup['blacklist'])) {
            return false;
        }
        return true;
    });

    // 处理无可用收件人的异常情况,避免程序卡死
    if (empty($validRecipients)) {
        die("配对失败:{$sup['surname']}没有符合条件的收件人,请检查名单或黑名单设置");
    }

    // 随机选中一个符合条件的收件人
    $randomKey = array_rand($validRecipients);
    $selectedRecipient = $validRecipients[$randomKey];

    // 记录配对结果
    $result[] = [
        'supplier' => $sup,
        'recipient' => $selectedRecipient
    ];

    // 从可选列表中移除已被选中的收件人,避免重复抽取
    unset($availableRecipients[$randomKey]);
}

// 输出最终配对结果
print_r($result);
?>

关键逻辑说明

  • 黑名单过滤:通过array_filter结合in_array,精准排除当前送礼人黑名单中的对象,同时保留“不能抽自己”的基础逻辑。
  • 可选收件人管理:维护独立的availableRecipients数组,每次配对后移除已选中的用户,确保每个人仅被抽取一次。
  • 随机选择优化:使用array_rand替代手动计算索引的rand,避免出现索引越界的错误。
  • 异常防护:添加空值判断,及时提示配对死锁问题,方便排查名单或黑名单的设置问题。

注意事项

  • 确保$sup['blacklist']是数组类型,存储的内容与收件人数组中的唯一标识(如ID、姓氏)完全匹配。
  • 若参与人数较多,建议在配对前先打乱$supplier数组的顺序,降低出现配对死锁的概率。

内容的提问来源于stack exchange,提问作者Clément Pageaux

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:05:17