gubbfett
gubbfett

Reputation: 2177

Sorting an array depending on different values

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
                )
        );

Upvotes: 0

Views: 69

Answers (2)

Mark Baker
Mark Baker

Reputation: 212412

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

Upvotes: 0

dynamic
dynamic

Reputation: 48091

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);

Upvotes: 1

Related Questions