A
A
Anton2019-06-28 14:59:46
PHP
Anton, 2019-06-28 14:59:46

How to implement an array grouping algorithm by value?

There is an array with days of the week and hours of work

$openingHours = [
            ['day' => 'monday', 'time' => '08:00-20:00'],
            ['day' => 'tuesday', 'time' => '08:00-20:00'],
            ['day' => 'wednesday', 'time' => '08:00-20:00'],
            ['day' => 'thursday', 'time' => '10:00-20:00'],
            ['day' => 'friday', 'time' => '10:00-18:00'],
            ['day' => 'saturday', 'time' => '10:00-16:00'],
            ['day' => 'sunday', 'time' => '10:00-16:00'],
        ];

It is necessary to group it so that days with the same working hours are combined into one element. More or less like this
$result = [
            'monday - wednesday' => '08:00-20:00',
            'thursday' => '10:00-20:00',
            'friday' => '10:00-18:00',
            'saturday - sunday' => '10:00-16:00',
        ];

How can this be achieved? Thank you!

Answer the question

In order to leave comments, you need to log in

4 answer(s)
D
Dmitry Koshelenko, 2019-06-28
@tohin15

Assuming the days of the week are in ascending order, you could use something like this:

$openingHours = [
    ['day' => 'monday', 'time' => '08:00-20:00'],
    ['day' => 'tuesday', 'time' => '08:00-20:00'],
    ['day' => 'wednesday', 'time' => '08:00-23:59'],
    ['day' => 'thursday', 'time' => '08:00-20:00'],
    ['day' => 'friday', 'time' => '08:00-20:00'],
    ['day' => 'saturday', 'time' => '10:00-16:00'],
    ['day' => 'sunday', 'time' => '10:00-16:00'],
];

$result = $active = [];

$openingHours[] = ['day' => '', 'time' => '']; // empty value to simplify code

foreach ($openingHours as $openingHour) {
    if ($active) {
        if ($active['time'] === $openingHour['time']) {
            $active['end'] = $openingHour['day'];
        } else {
            $key          = $active['end'] ? $active['start'] . '-' . $active['end'] : $active['start'];
            $result[$key] = $active['time'];
            $active       = [];
        }
    }
    $active = $active ?: [
        'time'  => $openingHour['time'],
        'start' => $openingHour['day'],
        'end'   => null,
    ];
}

print_r($result);

V
Vladimir Proskurin, 2019-06-28
@Vlad_IT

Head-on solution: create an associative array, where the key is time, the value is an array of days of the week. And just go through each element of $openingHours, take time from it, check if it is in our created array, if not, create and add a day there, if there is, then just add a day there.
Well, then write a function that will transform our created array into the one you need. This is also quite simple, we look at the key, take its values, connect them through the separator -, and use it as a key in a new array.

A
Anton, 2019-06-28
@Eridani

If, according to the plan, Vladimir Proskurin

$openingHours = [
            ['day' => 'monday', 'time' => '08:00-20:00'],
            ['day' => 'tuesday', 'time' => '08:00-20:00'],
            ['day' => 'wednesday', 'time' => '08:00-20:00'],
            ['day' => 'thursday', 'time' => '10:00-20:00'],
            ['day' => 'friday', 'time' => '10:00-18:00'],
            ['day' => 'saturday', 'time' => '10:00-16:00'],
            ['day' => 'sunday', 'time' => '10:00-16:00'],
        ];
$temp = array();
$result = array();

foreach($openingHours as $key => $item) {
  $temp[$item['time']][] = $item['day']; 
}
foreach($temp as $key => $item){
  $count = count($item) -1;
  $count >= 1 ? $result[$item[0].'-'.$item[$count]] = $key : $result[$item[0]] = $key; 
}
print_r($result);

Array
(
    [monday-wednesday] => 08:00-20:00
    [thursday] => 10:00-20:00
    [friday] => 10:00-18:00
    [saturday-sunday] => 10:00-16:00
)

PS I'll be happy to look at other implementations or simplifications of the above

S
Sergey Pliskin, 2019-06-28
@pligin

The result is an array with the days of the week in an ordered form. It remains only to come up with a function that will determine that the days go in a row without a break and put a "dash", otherwise a comma. I wrote it on the phone))) When I get to the computer, I’ll think it over

$openingHours = [
            ['day' => 'tuesday', 'time' => '08:00-20:00'],
            ['day' => 'wednesday', 'time' => '08:00-20:00'],
            ['day' => 'thursday', 'time' => '10:00-20:00'],
            ['day' => 'friday', 'time' => '10:00-18:00'],
            ['day' => 'saturday', 'time' => '10:00-16:00'],
            ['day' => 'sunday', 'time' => '10:00-16:00'],
            ['day' => 'monday', 'time' => '08:00-20:00'],
        ];
$template = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday'];
$new = array();
foreach ($openingHours as $key => $value){
  $new[$value['time']][] = $value['day'];
  $new[$value['time']] = array_intersect($template,$new[$value['time']]);
}
print_r($new);

Array
(
    [08:00-20:00] => Array
        (
            [1] => monday
            [2] => tuesday
            [3] => wednesday
        )

    [10:00-20:00] => Array
        (
            [4] => thursday
        )

    [10:00-18:00] => Array
        (
            [5] => friday
        )

    [10:00-16:00] => Array
        (
            [0] => sunday
            [6] => saturday
        )
)

Well, the keys are saved for the names of the days, you can add keys from 1 to 7 in the sorting template, so that in the future, if necessary, get the day of the week by the key (the ordinal number of the day in the week)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question