Задать вопрос
@GogenZZo

Режим работы из массива в одну строку?

Здравствуйте. Бьюсь над задачей долгое время, никак не могу сообразить =/
Есть массив вида

$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'],
];


Необходимо на выходе получить строку:

Пн-Пт: 08:00 - 20:00, Сб: 08:00 - 18:00, Вс: 10:00 - 15:00
  • Вопрос задан
  • 197 просмотров
Подписаться 1 Оценить 2 комментария
Помогут разобраться в теме Все курсы
  • Skillfactory
    Профессия Fullstack веб-разработчик на JavaScript и PHP
    20 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 1
miraage
@miraage
Старый прогер
<?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
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@Mercury13
Программист на «си с крестами» и не только
Скажем прямо: данная конструкция работает только если выходные дни в начале или конце недели. Если в середине — придётся расширять алгоритмы, да и труднолокализуема (языковые строки одновременно служат техническими ключами).

Заводим три переменных: firstDay, lastDay, workHours. Поначалу они пустые строки.
Проходимся по всем элементам.
• Если рабочие часы совпадают с workHours — перезаписываем lastDay, и всё.
• А если нет — проводим функцию dump, перезаписываем все три.
После цикла принудительно проводим dump.

Как должна работать функция dump.
• Если workHours пусто — ничего не делаем.
• Если результирующая строка непуста — добавляем разделитель.
• В зависимости от того, совпадают ли firstDay и lastDay, добавляем «Пн» или «Пн-Пт».
• Ну и, наконец, добавляем рабочие часы.
Ответ написан
Комментировать
AnnTHony
@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;
Ответ написан
Комментировать
Rastishka
@Rastishka
А в чем проблема, какой у вас код? Бежим циклом, по исходному массиву, генерируем новый массив:

Если предыдущее время работы != последнему добавленному,
добавляем строку в новый массив,
иначе
модифицируем последний элемент нового массива (добавляем новый день недели).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽