G
G
GogenZZo2016-12-12 13:46:32
PHP
GogenZZo, 2016-12-12 13:46:32

Operation mode from array to one line?

Hello. I've been struggling with the task for a long time, I just can't figure it out =/
There is an array of the form

$arr = [
 ['Пн', '08:00 - 20:00'],
 ['Вт', '08:00 - 20:00'],
 ['Ср', '08:00 - 20:00'],
 ['Чт', '08:00 - 20:00'],
 ['Пт', '08:00 - 20:00'],
 ['Сб', '08:00 - 18:00'],
 ['Вс', '10:00 - 15:00'],
];

You need to get the following line in the output:
Пн-Пт: 08:00 - 20:00, Сб: 08:00 - 18:00, Вс: 10:00 - 15:00

Answer the question

In order to leave comments, you need to log in

4 answer(s)
M
Mikhail Osher, 2016-12-12
@GogenZZo

<?php

$inputs = [
  [
    ['Пн', '08:00 - 20:00'],
    ['Вт', '08:00 - 20:00'],
    ['Ср', '08:00 - 20:00'],
    ['Чт', '08:00 - 20:00'],
    ['Пт', '08:00 - 20:00'],
    ['Сб', '08:00 - 18:00'],
    ['Вс', '10:00 - 15:00'],
  ],

  [
    ['Пн', '08:00 - 19:00'],
    ['Вт', '08:00 - 19:00'],
    ['Ср', '08:00 - 21:00'],
    ['Чт', '08:00 - 20:00'],
    ['Пт', '08:00 - 20:00'],
    ['Сб', '08:00 - 18:00'],
    ['Вс', '10:00 - 15:00'],
  ],
];

function is_consecutive(array $numbers)
{
  $count = count($numbers);

  if ($count < 2) {
    return false;
  }

  $first = $numbers[0];
  $range = range($first, $first + $count - 1);

  return $numbers === $range;
}

function format_day_times(array $input)
{
  $timeIndexes = [];

  foreach ($input as $index => list($day, $time)) {
    $timeIndexes[$time][] = [$index, $day];
  }

  $result = [];

  foreach ($timeIndexes as $time => $data) {
    if (is_consecutive(array_column($data, 0))) {
      $result[] = sprintf(
        '%s-%s: %s',
        $data[0][1],
        array_slice($data, -1)[0][1],
        $time
      );
    } else {
      foreach ($data as list(, $day)) {
        $result[] = sprintf('%s: %s', $day, $time);
      }
    }
  }

  return join(', ', $result);
}

foreach ($inputs as $input) {
  echo format_day_times($input), PHP_EOL;
}

Пн-Пт: 08:00 - 20:00, Сб: 08:00 - 18:00, Вс: 10:00 - 15:00
Пн-Вт: 08:00 - 19:00, Ср: 08:00 - 21:00, Чт-Пт: 08:00 - 20:00, Сб: 08:00 - 18:00, Вс: 10:00 - 15:00

M
Mercury13, 2016-12-12
@Mercury13

Let's face it: this construction only works if the weekend is at the beginning or end of the week. If in the middle, you will have to expand the algorithms, and it is difficult to localize (language strings simultaneously serve as technical keys).
We start three variables: firstDay, lastDay, workHours. At first they are empty strings.
Let's go through all the elements.
• If working hours coincide with workHours, we overwrite lastDay, and that's it.
• And if not, we carry out the dump function, overwrite all three.
After the cycle, we force a dump.
How the dump function should work.
• If workHours is empty, we do nothing.
• If the resulting string is not empty, add a separator.
• Depending on whether firstDay and lastDay match, add "Mon" or "Mon-Fri".
• And finally, we add working hours.

A
Anton Fedoryan, 2016-12-12
@AnnTHony

$arr = [
 ['Пн', '08:00 - 20:00'],
 ['Вт', '08:00 - 20:00'],
 ['Ср', '08:00 - 20:00'],
 ['Чт', '08:00 - 20:00'],
 ['Пт', '08:00 - 20:00'],
 ['Сб', '08:00 - 18:00'],
 ['Вс', '10:00 - 15:00'],
];

$res = "";
$i = 0;

do {
  $j = $i + 1;
  do {
    if ($arr[$i][1] <> $arr[$j][1]) {
      break;
    }
    $j++;
  } while ($j < count($arr));
  
  if (strlen($res) > 0) {
    $res .= ", ";
  }
  
  if ($i == $j - 1) {
    $res .= $arr[$i][0] . ": " . $arr[$i][1];
  }
  else {
    $res .= $arr[$i][0] . '-' . $arr[$j - 1][0] . ': ' . $arr[$i][1];
  }
  
  $i = $j;
} while ($i < count($arr));

echo $res;

R
Rastishka, 2016-12-12
@Rastishka

What is the problem, what code do you have? We loop through the original array, generate a new array:
If the previous work time != the last added,
add a string to the new array,
otherwise we
modify the last element of the new array (add a new day of the week).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question