Home > Blockchain >  PHP returning an element from an array
PHP returning an element from an array

Time:11-10

So I have some code that returns all the time in an array like this Open hours today: 9:00- 9:45, 9:55 - 10:20, 10:30 - 11:00 . If we used $formatted_ranges[array_key_first($formatted_ranges)] instead of join, it would return a single element as like this, "Open hours today: 9:00 - 9:45". However we need to return like this,

Open hours today: 9:00 - 11:00.

$start = DateTime::createFromFormat( 'H:i', $range['from'] );
$end = DateTime::createFromFormat( 'H:i', $range['to'] );

$formatted_ranges = array_map( function( $range ) {
            return $this->format_time( $range['from'] ).' - '.$this->format_time($range['to'] );
}, $ranges );

return sprintf(
  __( 'Open hours today:', 'example' ) . ' <span>%s</span>',
            join( ', ', $formatted_ranges )
        );

CodePudding user response:

The originally shared code was not runnable. From the question, I think you want to reformat a time range array to find the beginning and the end of all the ranges.

As long as all the time are represented as 24-hour clock format, this is an example of how it can be done.

<?php

/**
 * Convert multiple ranges into a single range.
 *
 * @param array $ranges
 * @return array
 */
function overallRanges(array $ranges): array {
  if (sizeof($ranges) === 0) {
    throw new \Exception('The provided ranges array is empty');
  }
  $range = array_reduce($ranges, function ($carry, $current) {
    $from = DateTime::createFromFormat('H:i', $current['from']);
    $to = DateTime::createFromFormat('H:i', $current['to']);
    $carry['from'] = ($from < $carry['from']) ? $from : $carry['from'];
    $carry['to'] = ($to > $carry['to']) ? $to : $carry['to'];
    return $carry;
  },
    [
      'from' => DateTime::createFromFormat('H:i', $ranges[0]['from']),
      'to' => DateTime::createFromFormat('H:i', $ranges[0]['to']),
    ]
  );
  return [
    'from' => $range['from']->format('G:i'),
    'to' => $range['to']->format('G:i'),
  ];
}

// example use
$ranges = [
  ['from' => '9:00', 'to' => '9:45'],
  ['from' => '9:55', 'to' => '10:20'],
  ['from' => '10:30', 'to' => '11:00'],
];

var_dump(overallRanges($ranges));

The output:

array(2) {
  ["from"]=>
  string(5) "9:00"
  ["to"]=>
  string(5) "11:00"
}

Should be a good enough start for you to reformat into anything.

CodePudding user response:

If I understand the input data correctly, you don't need to iterate and reformat every element in the multidimensional array.

Just access the from from the first row and the to from the last row and you're done. Format just those two values if necessary.

Code: (Demo)

$ranges = [
    ['from' => '9:00', 'to' => '9:45'],
    ['from' => '9:55', 'to' => '10:20'],
    ['from' => '10:30', 'to' => '11:00'],
];

if (!isset($ranges[0]['from'], $ranges[0]['to'])) {
    throw new Exception('insufficient business hours data');
}
printf(
    'Open hours today: %s - %s',
    $ranges[0]['from'],
    $ranges[array_key_last($ranges)]['to']
);

Output:

Open hours today: 9:00 - 11:00
  • Related