如何检查值是否不在数组中并生成对应的非工作日列表
如何检查值是否不在数组中并生成对应的非工作日列表 本文介绍在 PHP 中高效判断当前日期是否未出现在分组工作日数组中,并据此构建非工作日列表的完整实现方法,涵盖 array_column 与 in_array 的正确组合用法、避免重复逻辑、日期格式对齐及结构化输出。 在考勤或排班系统的开发中,我们常
如何检查值是否不在数组中并生成对应的非工作日列表
本文介绍在 PHP 中高效判断当前日期是否未出现在分组工作日数组中,并据此构建非工作日列表的完整实现方法,涵盖 array_column 与 in_array 的正确组合用法、避免重复逻辑、日期格式对齐及结构化输出。

在考勤或排班系统的开发中,我们常常会遇到一个经典场景:需要根据预设的「工作日规则」,动态判断今天是不是某个组的「非工作日」。具体来说,给定一个包含 `group_id` 和 `day`(其中1代表周日,2代表周一,以此类推至7代表周六)的对象数组 `$work_day_arr`,目标是要找出所有没有将今天设置为工作日的分组,并生成一个结构清晰的 `$day_off` 列表,其格式类似于 `['attendance_group_id' => 'xxx', 'off_date' => 'Y-m-d']`。
听起来很直接,对吧?但实际操作时,一些常见的实现陷阱会让结果偏离预期。先来看看原代码中暴露的三个关键问题:
- 逻辑错误:代码中间出现了 `if($work_day->day != $day_now + 1)`,这里的 `$work_day` 变量并未定义(本意应是 `$work_hour`)。更麻烦的是,PHP 的 `date('N')` 返回的是 1(周一)到 7(周日),而业务数据里 `day=1` 表示的是周日,两者语义完全对不上。
- 重复写入:原逻辑针对每一条不匹配的工作日记录,都会向结果数组追加一条记录。这直接导致同一个 `group_id` 在结果中重复出现多次,数据冗余严重。
- 检测粒度错误:问题的核心在于,判断依据应该是「每个 `group_id` 维度下,其工作日集合是否完全不含今天」,而不是逐条记录进行比对。这个根本性的差异决定了整个算法的设计方向。
那么,正确的解决思路是什么?其实可以归纳为一个清晰的步骤:先按 `group_id` 分组,再提取各组的工作日数字集合,最后检查当前的星期几是否不在该集合中。这里,`array_column()` 配合 `in_array()` 将成为我们的核心工具。
// 1. 获取今日星期几(PHP date('N'):1=周一, 7=周日)
$todayWeekday = (int) date('N');
// 注意:数据中 day=1 表示周日 → 需统一映射!
// 2. 修正日期映射:将 date('N') 转为「1=周日」标准(即:周日→1,周一→2...周六→7)
$normalizedToday = $todayWeekday === 1 ? 7 : $todayWeekday - 1; // 1→7, 2→1, 3→2...7→6
// 3. 按 group_id 分组工作日数据
$groupedWorkDays = [];
foreach ($work_day_arr as $item) {
$groupId = $item->group_id;
if (!isset($groupedWorkDays[$groupId])) {
$groupedWorkDays[$groupId] = [];
}
$groupedWorkDays[$groupId][] = (int) $item->day;
}
// 4. 遍历每个分组,检查 normalizedToday 是否不在其工作日列表中
$day_off = [];
$date_now = date('Y-m-d'); // 确保日期格式统一
foreach ($groupedWorkDays as $groupId => $workDays) {
// 使用 in_array 检查当前标准化星期几是否缺失
if (!in_array($normalizedToday, $workDays, true)) {
$day_off[] = (object) [
'attendance_group_id' => $groupId,
'off_date' => $date_now
];
}
}
实现代码如上,但有几个关键注意事项必须牢记,它们直接关系到程序的正确性与健壮性:
- 日期映射必须统一:这是最容易出错的一环。`date('N')` 以周一为1,而业务数据以周日为1。因此,必须进行转换(`$normalizedToday = $todayWeekday === 1 ? 7 : $todayWeekday - 1`),确保比较是在同一套标准下进行。
- 避免重复:有人可能会想直接用 `array_column($work_day_arr, 'day', 'group_id')` 来分组,但这个方法会覆盖同一 `group_id` 的多条记录,无法满足我们收集所有工作日需求。手动分组是更稳妥的选择。
- 严格类型比较:在使用 `in_array()` 时,务必启用严格模式(第三个参数设为 `true`),即 `in_array($val, $arr, true)`。这可以防止因 `1 == '1'` 这类隐式类型转换而导致的误判。
- 性能提示:如果初始数据量非常大,可以考虑在分组后对每个 `$workDays` 数组使用 `array_unique()` 去重,再用 `array_values()` 重置索引。这在某些极端场景下能带来一定的性能优化。
遵循以上方法和注意事项,最终生成的 `$day_off` 列表将为每一个「未安排今日工作」的分组,产出唯一一条记录。整个输出结构清晰,毫无冗余,完全满足生产环境对代码健壮性和数据准确性的要求。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
AWS RDS 数据库配置入门与基础操作指南
本文介绍了AWSRDS的基本概念与核心价值,即提供托管式关系数据库服务,简化运维。详细阐述了创建RDS实例的关键配置步骤,包括引擎选择、实例规格、存储与网络设置。最后,指导读者如何通过多种方式安全连接至数据库实例,并开始进行数据操作,为后续应用开发奠定基础。
PHP MVC中AJAX请求无法调用控制器方法的原因与解决方案
PHPMVC中AJAX请求返回整页HTML的常见原因是控制器方法未正确输出响应或未终止执行,导致框架渲染视图。解决方法是在控制器中设置JSON响应头、输出数据后调用exit()明确终止,同时前端使用小写url和dataType: "json "。
Go语言手动构造rsa.PublicKey:正确初始化大整数模数N完整指南
手动构造RSA公钥时,模数N为*big Int类型,不能直接使用超长十进制字面量,需通过SetString或UnmarshalText方法解析字符串。公钥指数E可直接赋值,推荐65537。生产环境应使用rsa GenerateKey生成密钥对,避免手动构造引发的安全和格式错误。
Go语言实现HTTP定时轮询监控多URL响应时间与状态检测
使用Go语言实现HTTP定时轮询监控,通过按行分割与Tab解析URL列表,避免闭包陷阱和nil指针,每个URL启动独立ticker安全并发请求,并配置超时控制与资源关闭,确保响应时间与状态码准确检测。
Tkinter中Label标签在主循环动态更新的正确方法
在Tkinter中正确动态更新标签的方法:将标签组件的textvariable参数绑定到一个StringVar变量,然后通过调用该变量的 set()方法更新其值,界面会自动刷新。这样避免直接修改text属性或调用update()。此做法实现数据与界面的解耦,代码更简洁,响应更及时,避免手动同步的闪烁,推荐做法。
- 热门数据榜
相关攻略
2026-07-10 06:41
2026-07-10 06:40
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

