Это первый раз, когда я использовал «оператор космического корабля» или «оператор трехстороннего сравнения» в фрагменте, который не вызывал usort()
.
Он идеально подходит для этой задачи, потому что вы хотите сгенерировать три сегмента для ваших значений времени.
Оператор космического корабля возвращает одно из трех различных значений: -1
, 0
и 1
. Его задача состоит в том, чтобы сравнить две строки и решить, является ли значение слева less than
, equal to
или greater than
значением правой стороны - тогда оно возвращает соответствующее числовое значение, упомянутое в моем предыдущем предложении.
Чтобы настроить этот уникальный оператор сравнения (доступный с php7 +), нам нужно свести входные числа так, чтобы они могли быть правильно «объединены».
Большинство людей спешат на explode()
(и слишком часто не используют 3-й параметр (limit), чтобы сообщить php, что требуется не более 2 элементов). Я этого не делаю, потому что мне не нравится генерировать массив из строки только для захвата подстроки. Поскольку значения времени предсказуемо отформатированы, лучшим инструментом для этой задачи будет substr($time, 0, 2)
, но за ним следует strstr($time, ':', true)
, а если вы хотите быть хитрым "$time[0]$time[1]"
.
Надеюсь, мои встроенные комментарии прояснят любые другие недоразумения по поводу моего сжатого и мощного фрагмента. (Всего 4 строки рабочего кода!)
Код: ( Демо )
$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]