Вычисление доступного времени из переназначенного массива в php возвращает один массив

#php #arrays

#php #массивы

Вопрос:

В моем коде есть следующая логика. Что делается, так это вычисление временных блоков из 15,30,45,60,90. Затем объединение массивов. Затем у меня есть foreach, который преобразует значения из вызова api и устанавливает их в новый массив. Что я пытаюсь сделать, так это сравнить значения времени из моего foreach с $combined_total_times и выполнить a array_diff_assoc с новым значением times, чтобы оно возвращало только те значения, которые не находятся в каждом времени массива.

 function hoursRange( $lower = 0, $upper = 86400, $step = 3600, $format = '' ) {
        $times = array();

        if ( empty( $format ) ) {
            $format = 'g:i a';
        }

        foreach ( range( $lower, $upper, $step ) as $increment ) {
            $increment = gmdate( 'H:i', $increment );

            list( $hour, $minutes ) = explode( ':', $increment );

            $date = new DateTime( $hour . ':' . $minutes );

            $times[] = $date->format( $format );
        }

        return $times;
    }

///counts how many 30,45,60,75 min blocks there is from 8-5pm
  $total_15 = hoursRange( 28800, 61200, 60 * 15, 'h:i a' );
  $total_30 = hoursRange( 28800, 61200, 60 * 30, 'h:i a' );
  $total_45 = hoursRange( 28800, 61200, 60 * 45, 'h:i a' );
  $total_60 = hoursRange( 28800, 61200, 60 * 60, 'h:i a' );
  $total_75 = hoursRange( 28800, 61200, 60 * 75, 'h:i a' );
  $total_90 = hoursRange( 28800, 61200, 60 * 90, 'h:i a' );
////
 $combined_total_times = array_merge($total_15,$total_30,$total_45,$total_60,$total_75,$total_90);

foreach ($result as $value)
{
    $strDay = date('D', strtotime($value['AptDate']));
    $strTime = date("h:i a", strtotime($value['AptTime']));
    if(isset($temp[$value['Location']])){
        $oldIndex = $temp[$value['Location']];
        $remappedData[$oldIndex][$strDay. '_date'] = $value['AptDate'];
        $remappedData[$oldIndex][$strDay. '_time'][] = $strTime;
    }
    else{
        $temp[$value['Location']] =   $intCurrentIndex;
        $remappedData[$intCurrentIndex]['location'] = $value['Location'];
        $remappedData[$intCurrentIndex][$strDay. '_date'] = $value['AptDate'];
        $remappedData[$intCurrentIndex][$strDay. '_time'][] = $strTime;
    }

}
  

Это пример переназначенного foreach .

 [{"location":"City 1","Mon_date":"2020-09-21","Mon_time":["08:00 am","08:30 am","10:00 am","11:00 am","11:45 am","01:30 pm","02:30 pm","03:30 pm","04:15 pm","08:00 am","08:30 am","09:00 am","10:15 am","11:30 am","01:00 pm","02:30 pm","03:45 pm","09:15 am","10:30 am","11:15 am","01:00 pm","02:15 pm","04:00 pm","04:45 pm","08:00 am","10:00 am","11:30 am","01:00 pm","02:15 pm","03:15 pm","04:00 pm","08:00 am","09:00 am","09:30 am","10:00 am","11:15 am","01:00 pm","03:15 pm","04:00 pm","08:00 am","09:00 am","09:45 am","11:00 am","01:30 pm","02:00 pm","04:15 am","04:30 am","04:45 am","05:00 am","05:15 am"],"Tue_date":"2020-09-22","Tue_time":["09:00 am","10:15 am","11:00 am","02:00 pm","03:00 pm","04:00 pm","08:00 am","10:00 am","01:00 pm","01:30 pm","02:15 pm","03:30 pm","08:00 am","10:00 am","11:15 am","01:00 pm","02:15 pm","03:30 pm","08:00 am","09:00 am","11:00 am","01:00 pm","02:00 pm","03:15 pm","04:00 pm","08:00 am","09:00 am","09:30 am","11:15 am","01:00 pm","02:00 pm"]}]
  

Что я пробовал, так это сначала массивировать разницу, а затем передавать это значение вниз, но это как бы помещает его в отдельный массив для каждого. :

Однако это разбивает результаты на один массив (см. Пример результатов ниже). Я пытаюсь получить разницу в одном единственном массиве.(см. Ожидаемые результаты)

  $strTime = explode(' ',  date("h:i a", strtotime($value['AptTime'])));
        $total_available = array_diff_assoc($strTime,$combined_total_times);  
  

пример результатов после попытки с моим решением:

 [{"location":"City 1","Mon_date":"2020-09-21","Mon_time":[["08:00","am"],["08:30","am"],["10:00","am"],["11:00","am"],["11:45","am"],["01:30","pm"],["02:30","pm"],["03:30","pm"],["04:15","pm"],["08:00","am"],["08:30","am"],["09:00","am"],["10:15","am"],["11:30","am"],["01:00","pm"],["02:30","pm"],["03:45","pm"],["09:15","am"],["10:30","am"],["11:15","am"],["01:00","pm"],["02:15","pm"],["04:00","pm"],["04:45","pm"],["08:00","am"],["10:00","am"],["11:30","am"],["01:00","pm"],["02:15","pm"],["03:15","pm"],["04:00","pm"],["08:00","am"],["09:00","am"],["09:30","am"],["10:00","am"],["11:15","am"],["01:00","pm"],["03:15","pm"],["04:00","pm"],["08:00","am"],["09:00","am"],["09:45","am"],["11:00","am"],["01:30","pm"],["02:00","pm"],["04:15","am"],["04:30","am"],["04:45","am"],["05:00","am"],["05:15","am"]],"Tue_date":"2020-09-22","Tue_time":[["09:00","am"],["10:15","am"],["11:00","am"],["02:00","pm"],["03:00","pm"],["04:00","pm"],["08:00","am"],["10:00","am"],["01:00","pm"],["01:30","pm"],["02:15","pm"],["03:30","pm"],["08:00","am"],["10:00","am"],["11:15","am"],["01:00","pm"],["02:15","pm"],["03:30","pm"],["08:00","am"],["09:00","am"],["11:00","am"],["01:00","pm"],["02:00","pm"],["03:15","pm"],["04:00","pm"],["08:00","am"],["09:00","am"],["09:30","am"],["11:15","am"],["01:00","pm"],["02:00","pm"]]}] 
  

ожидаемые результаты:

 [{"location":"City 1","Mon_date":"2020-09-21","Mon_time":["08:00","08:30","10:00","11:00","11:45","01:30","02:30","03:30","04:15","08:00","08:30","09:00","10:15","11:30","01:00","02:30","03:45"
  

(и т.д. и т.п.)

Ответ №1:

Все вычисляемые вами блоки( 30,45,60,75,90 ) кратны 15 только. Итак, ваш первый массив total_15 содержит все блоки, которые будут доступны после объединения всех этих массивов. Так что просто сделайте

 $total_15 = hoursRange( 28800, 61200, 60 * 15, 'h:i a' );
// If you don't wanna change code after this line, assign it to combined one.
$combined_total_times = $total_15;
  

Сначала установите все значения $total_15 как доступные и удаляйте одно за другим, если time они найдены во время цикла.

 foreach ($result as $value)
{
    $strDay = date('D', strtotime($value['AptDate']));
    $strTime = date("h:i a", strtotime($value['AptTime']));
    
    
    
    if(isset($temp[$value['Location']])){
        $oldIndex = $temp[$value['Location']];
        $remappedData[$oldIndex][$strDay. '_date'] = $value['AptDate'];
        $remappedData[$oldIndex][$strDay. '_time'][] = $strTime;
        
        if(isset($remappedData[$oldIndex][$strDay. '_new'])){
            // remove this time from $strDay_new array.
            $pos = array_search($strTime, $remappedData[$oldIndex][$strDay. '_new']);
            unset($remappedData[$oldIndex][$strDay. '_new'][$pos]);
        }
        else{
            // There can be multiple days in a location. If this is first record for a day then set it to $total_15 except $strTime.
            $remappedData[$oldIndex][$strDay. '_new'] = array_diff($total_15, [$strTime]);
        }
        
        // 
    }
    else{
        $temp[$value['Location']] =   $intCurrentIndex;
        $remappedData[$intCurrentIndex]['location'] = $value['Location'];
        $remappedData[$intCurrentIndex][$strDay. '_date'] = $value['AptDate'];
        $remappedData[$intCurrentIndex][$strDay. '_time'][] = $strTime;
        // Set when new day index found.
        $remappedData[$intCurrentIndex][$strDay. '_new'] = array_diff($total_15, [$strTime]);;
    }
}
  

Комментарии:

1. То, что я пытаюсь сделать, это взять все времена, которых НЕТ в $$combined_total_times, и вернуть различия. Это будут «НОВЫЕ» доступные времена. Все времена в вызове api — это время, которое забронировано. Мне нужно посмотреть, что доступно, на основе сравнения $combined_total_times со временем вызова api. Имеет ли это смысл?

2. ошибка при array_search. array_search() ожидает, что параметр 2 будет array

3. не total_15 является ли это массивом?

4. да, это так. Я думаю $remappedData[$oldIndex][$strDay. '_new'] , что это не так?

5. но мы назначили total_15 то $remappedData[$intCurrentIndex][$strDay. '_new'] = $total_15; же самое. смотрите последнюю строку.