0

Lets say you have an array of days and openinghours for a shop like this:

Array
(
    [monday] => Array
        (
            [day] => Monday
            [isopen] => true
            [open] => 10:00
            [close] => 17:00
        )

    [tuesday] => Array
        (
            [day] => Tuesday
            [isopen] => true
            [open] => 10:00
            [close] => 17:00
        )

    [wednesday] => Array
        (
            [day] => Wednesday
            [isopen] => true
            [open] => 10:00
            [close] => 17:00
        )

    [thursday] => Array
        (
            [day] => Thursday
            [isopen] => true
            [open] => 10:00
            [close] => 17:00
        )

    [friday] => Array
        (
            [day] => Friday
            [isopen] => true
            [open] => 10:00
            [close] => 17:00
        )

    [saturday] => Array
        (
            [day] => Saturday
            [isopen] => false
            [open] => 11:00
            [close] => 14:00
        )

    [sunday] => Array
        (
            [day] => Sunday
            [isopen] => false
            [open] => 01:00
            [close] => 01:00
        )

)

now, i want to sort these babies like this:

monday - friday: 10:00-17:00
saturday-sunday: closed

lest say wednesday was closing 16:00 i would like this output:

monday-tuesday: 10:00-17:00
wednesday: 10:00-16:00
thursday-friday: 10:00-17:00
saturday-sunday: closed

That is, I want to sort them but still keep the order from top to bottom as the primary sorting. So, how would you do it? Loop them all and keep hours in memory and compare days is one option but is'nt there any nicer solution?

EDIT: An actual array was requested, here it is:

$days = array(
            'monday' => array(
                    'day' => 'Monday',
                    'isopen' => true,
                    'open' => '10:00',
                    'close' => '17:00',
                ),
            'tuesday' => array(
                    'day' => 'Tuesday',
                    'isopen' => true,
                    'open' => '10:00',
                    'close' => '17:00',
                ),
            'wednesday' => array(
                    'day' => 'Wednesday',
                    'isopen' => true,
                    'open' => '10:00',
                    'close' => '17:00',
                ),
            'thursday' => array(
                    'day' => 'Thursday',
                    'isopen' => true,
                    'open' => '10:00',
                    'close' => '17:00',
                ),
            'friday' => array(
                    'day' => 'Friday',
                    'isopen' => true,
                    'open' => '10:00',
                    'close' => '17:00',
                ),
            'saturday' => array(
                    'day' => 'Saturday',
                    'isopen' => false,
                    'open' => '10:00', //Not used since isopen = false
                    'close' => '17:00', //Not used since isopen = false
                ),
            'sunday' => array(
                    'day' => 'Sunday',
                    'isopen' => false,
                    'open' => '10:00', //Not used since isopen = false
                    'close' => '17:00', //Not used since isopen = false
                )
        );
4
  • 1
    That isn't "sorting" the array, it's "merging" array entries, and there isn't any built-in function that will do it for you, so you'll basically need to loop through the array checking the values and merging them manually Commented Nov 10, 2014 at 10:50
  • 2
    I guess I could answer your question, but... you posted var_dumped data which I can't just grab, paste in my IDE and play with... and I'm too lazy to convert it back to php. Sorry. Commented Nov 10, 2014 at 10:52
  • Exactly what @georg said, I think I have an answer to this but in order for us to help you, you have to help us help you, if that makes any sense. Commented Nov 10, 2014 at 11:08
  • Sure, I added it now. My intentions were not no make you guys write it for me, but of course i would like to see your code! :) Commented Nov 10, 2014 at 12:20

2 Answers 2

1

That is tricky, but not that impossible (and be aware it is a sort of merging rather than sorting):

    $sorted = array();
    foreach($days as $k=>$v){

        $current = array(
            'open'=>$v['open'],
            'close'=>$v['close'],
            'isopen'=>$v['isopen'],
        );              

        if (empty($sorted) || $previous != $current ) {
            $sorted[] = array('firstDay'=>$k,'open'=>$v['open'],'close'=>$v['close']);
        } else
            $sorted[count($sorted)-1]['lastDay'] = $k;


        $previous = $current;   
    }

    print_r($sorted);
Sign up to request clarification or add additional context in comments.

Comments

0

Something like:

$newArray = array();
$dayCount = -1;
foreach ($days as $day) {
    if ( ($dayCount < 0) || 
         ($day['isopen'] != $newArray[$dayCount]['isopen']) || 
         ($day['open'] != $newArray[$dayCount]['open']) || 
         ($day['close'] != $newArray[$dayCount]['close']) ) {
        $newArray[++$dayCount] = array_merge(
            $day,
            array('dayTo' => '')
        );
    } else {
        $newArray[$dayCount]['dayTo'] = $day['day'];
    }
}
var_dump($newArray);

EDIT

From your posted initial array, this gives:

array(2) {
  [0]=>
  array(5) {
    ["day"]=>
    string(6) "Monday"
    ["isopen"]=>
    bool(true)
    ["open"]=>
    string(5) "10:00"
    ["close"]=>
    string(5) "17:00"
    ["dayTo"]=>
    string(6) "Friday"
  }
  [1]=>
  array(5) {
    ["day"]=>
    string(8) "Saturday"
    ["isopen"]=>
    bool(false)
    ["open"]=>
    string(5) "10:00"
    ["close"]=>
    string(5) "17:00"
    ["dayTo"]=>
    string(6) "Sunday"
  }
}

If you have mismatched open and close values on "closed" days, then changing the if condition to

if ( ($dayCount < 0) || 
     ($day['isopen'] != $newArray[$dayCount]['isopen']) || 
     ($day['isopen'] && (($day['open'] != $newArray[$dayCount]['open']) || 
                         ($day['close'] != $newArray[$dayCount]['close']) ))) {

might help

2 Comments

I love this solution. It does not, how ever, "group" the closed days. That is, it gets 3 values in the array, when it should be 2 values; "dayTo" should be "sunday" on "saturday". Otherwise this is brilliant.
My test run did give dayTo of "sunday" on "saturday" from your posted array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.