这是我第一次在不调用 usort() 的 sn-p 上使用“宇宙飞船运算符”又名“3 路比较运算符”。
它非常适合这项任务,因为您想为您的时间值生成三个存储桶。
spaceship 运算符返回三个不同值之一:-1、0 和 1。它的工作是比较两个字符串并确定左侧的值是less than、equal to 还是greater than 右侧的值——然后返回我上一句中提到的相应数值。
要设置这个唯一的比较运算符(可从 php7+ 获得),我们需要将输入的数字归结为可以正确“分桶”。
大多数人都急于explode()(并且经常不使用第三个参数(限制)来通知 php 需要不超过 2 个元素)。我不这样做,因为我不喜欢仅仅为了捕获子字符串而从字符串生成数组。因为时间值的格式是可预测的,所以完成任务的最佳工具是substr($time, 0, 2),但紧随其后的是strstr($time, ':', true),如果你想变得棘手,"$time[0]$time[1]"。
我希望我的内联 cmets 能够消除关于我简洁而强大的 sn-p 的任何其他困惑。 (只需 4 行工作代码!)
代码:(Demo)
$time_array = ["17:45", "13:12", "09:29", "17:32", "16:49", "14:18"];
$buckets = array_fill_keys([-1, 0, 1], 0); // initialize buckets with 0 values
foreach ($time_array as $time) {
++$buckets[(int)sqrt(substr($time, 0, 2) - 8) <=> 2];
// ^^^^^-- 3-way comparison versus 2
// ^^^--------- subtract 8 from the two-digit number
// ^^^^^^^^^^^^^^^^^^^------------- extract first two digits from time string
// ^^^^^^-------------------------------- get squareroot value
// ^^^^--------------------------------- convert to integer (truncate decimals)
}
echo "Morning Count: {$buckets[-1]}\n"; // Hours: 00:00 to 11:59 ->12hrs (calculates as: 0, 1)
echo "Afternoon Count: {$buckets[0]}\n"; // Hours: 12:00 to 16:59 -> 5hrs (calculates as: 2)
echo "Evening Count: {$buckets[1]}"; // Hours: 17:00 to 23:59 -> 7hrs (calculates as: 3, 4)
输出:
Morning Count: 1
Afternoon Count: 3
Evening Count: 2
计算过程如何分解?
foreach (range(0, 23) as $t) {
$calc = (float)sqrt($t - 8);
echo "$t: " , (int)$calc , " ... [float value from sqrt was: $calc]\n";
}
从时间值0 到23 的细分:
// |--------------------------------------------input time value
// v v-----------------------------------------final calculated value
// vvv-----before converted to integer value
0: 0 ... [float value from sqrt was: NAN]
1: 0 ... [float value from sqrt was: NAN]
2: 0 ... [float value from sqrt was: NAN]
3: 0 ... [float value from sqrt was: NAN]
4: 0 ... [float value from sqrt was: NAN]
5: 0 ... [float value from sqrt was: NAN]
6: 0 ... [float value from sqrt was: NAN]
7: 0 ... [float value from sqrt was: NAN]
8: 0 ... [float value from sqrt was: 0]
9: 1 ... [float value from sqrt was: 1]
10: 1 ... [float value from sqrt was: 1.4142135623731]
11: 1 ... [float value from sqrt was: 1.7320508075689]
12: 2 ... [float value from sqrt was: 2]
13: 2 ... [float value from sqrt was: 2.2360679774998]
14: 2 ... [float value from sqrt was: 2.4494897427832]
15: 2 ... [float value from sqrt was: 2.6457513110646]
16: 2 ... [float value from sqrt was: 2.8284271247462]
17: 3 ... [float value from sqrt was: 3]
18: 3 ... [float value from sqrt was: 3.1622776601684]
19: 3 ... [float value from sqrt was: 3.3166247903554]
20: 3 ... [float value from sqrt was: 3.4641016151378]
21: 3 ... [float value from sqrt was: 3.605551275464]
22: 3 ... [float value from sqrt was: 3.7416573867739]
23: 3 ... [float value from sqrt was: 3.8729833462074]