Я рассчитываю подсчитать значения из массива, который содержит определенное число. По сути, я планирую построить график посещений и хочу сделать это «утром», «днем» и «вечером». Поэтому я хочу посчитать время, например, 17:38
как 17
, затем подсчитайте их, чтобы я мог классифицировать, были ли посещения утром, днем или вечером.
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
$counts = array_count_values($time_array);
$morning_counts = $counts['09'] + $counts['10'] + $counts['11'];
$afternoon_counts = $counts['12'] + $counts['13'] + $counts['14'] + $counts['15'] + $counts['16'];
$evening_counts = $counts['17'] + $counts['18'] + $counts['19'] + $counts['20'] + $counts['21'] + $counts['22'] + $counts['23'];
Ожидаемый выход из выборочных данных:
$morning_counts = 1
$afternoon_count = 3
$evening_counts = 2
Вы можете сделать это, создав переменные счетчика. Затем мы можем создать диапазоны временных интервалов, используя range()
, Затем получите значения до :
в строке времени как час, а затем сравните это с диапазоном, если он находится в диапазоне, добавьте 1 к счетчику.
<?php
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
# create counter vars
$mornCount = 0;
$afternoonCount = 0;
$eveCount = 0;
# create range of times to compare against
$mornRange = range(0, 11);
$afternoonRange = range(12, 16);
$eveRange = range(17, 23);
foreach ($time_array as $time)
{
$compareTimeArr = explode(':', $time); # get first two chars of time
$compareTime = $compareTimeArr[0];
if (in_array($compareTime, $mornRange)) {
$mornCount++;
} elseif (in_array($compareTime, $afternoonRange)) {
$afternoonCount++;
} elseif (in_array($compareTime, $eveRange)) {
$eveCount++;
}
}
echo '<pre>'. print_r($mornCount,1) .'</pre>';
echo '<pre>'. print_r($afternoonCount,1) .'</pre>';
echo '<pre>'. print_r($eveCount,1) .'</pre>';
рефов:
https://secure.php.net/manual/en/function.in-array.php
Самый простой вариант:
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
$times = [];
foreach ($time_array as $time) {
$times[] = substr($time, 0, 2);
}
// Proceed with original code, but swap $time_array for $times
Я думаю, что это довольно уродливо, хотя. Я бы обычно рекомендовал работать с DateTimes или DatePeriods вместо строк.
Будучи ДЕЙСТВИТЕЛЬНО упрощенным, вы можете сделать это в выражении switch
<?php
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
$morn = 0;
$after = 0;
$eve = 0;
$other = 0;
foreach ($time_array as $time) {
$t = explode(':',$time)[0];
switch ($t) {
case '09':
case '10':
case '11':
case '12':
$morn++;
break;
case '13':
case '14':
case '15':
case '16':
$after++;
break;
case '17':
case '18':
case '19':
case '20':
case '21':
case '22':
case '23':
$eve++;
break;
default:
$other++;
}
}
echo "Morning = $morn<br>";
echo "Afternoon = $after<br>";
echo "Evening= $eve<br>";
echo "Other = $other<br>";
Это должно сделать это всего за несколько строк:
$counts = array_reduce($time_array, function($counts, $time) {
$hour = (int)substr($time, 0, 2);
$moment = in_array($hour, range(9, 12)) ? 'morning' : (in_array($hour, range(13, 16)) ? 'afternoon' : 'evening');
$counts[$moment]++;
return $counts;
}, ['morning' => 0, 'afternoon' => 0, 'evening' => 0]);
Здесь приходит другое решение
<?php
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
$counts = countValues($time_array);
$morning_counts = $counts['09'] + $counts['10'] + $counts['11'] + $counts['12'];
$afternoon_counts = $counts['12'] + $counts['13'] + $counts['14'] + $counts['15'] + $counts['16'];
$evening_counts = $counts['17'] + $counts['18'] + $counts['19'] + $counts['20'] + $counts['21'] + $counts['22'] + $counts['23'] + $counts['24'];
var_dump($morning_counts, $afternoon_counts, $evening_counts);
function countValues($time_array) {
$result = [];
for ($i = 0; $i <= 23; $i++) {
$key = ($i < 10) ? ('0' . $i) : (string) $i;
$result[$key] = 0;
}
foreach ($time_array as $time) {
$key = strstr($time, ':', true);
$result[$key]++;
}
return $result;
}
С помощью preg_match
Вы также можете получить количество раз.
$time_array = array("17:45","13:12","09:29","17:32","16:49","14:18");
function time_results($time_array){
$result = array('morning_counts'=>0,'afternoon_counts'=>0,'evening_counts'=>0,'total'=>0);
$result['total'] = count($time_array);
foreach($time_array as $time){
if(preg_match('/^(09|10|11|12)\:*/',$time)){
$result['morning_counts'] += 1;
}else if(preg_match('/^(13|14|15|16)\:*/',$time)){
$result['afternoon_counts'] += 1;
}else if(preg_match('/^(17|18|19|20|21|22|23|24)\:*/',$time)){
$result['evening_counts'] += 1;
}
}
return $result;
}
var_dump(time_results($time_array));
/*
result : array(4) { ["morning_counts"]=> int(1) ["afternoon_counts"]=> int(3) ["evening_counts"]=> int(2) ["total"]=> int(6) }
*/
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]