Сортировка массива в зависимости от разных значений

0

Допустим, у вас есть множество дней и открытий для магазина вроде этого:

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
        )

)

теперь, я хочу сортировать этих детей следующим образом:

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

чтобы сказать, что среда закрылась 16:00, мне бы хотелось, чтобы этот результат:

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

То есть, я хочу сортировать их, но все равно сохраняю порядок сверху вниз в качестве первичной сортировки. Итак, как бы вы это сделали? Зациклируйте их все и сохраните часы в памяти, а сравнить дни - это один из вариантов, но нет ли лучшего решения?

EDIT: запрошен фактический массив, вот он:

$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
                )
        );
Теги:
arrays
sorting

2 ответа

0
Лучший ответ

Что-то вроде:

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

РЕДАКТИРОВАТЬ

Из опубликованного исходного массива это дает:

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"
  }
}

Если вы несовпадающие open и close значения на "закрытые" дни, то изменение, if условия для

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

может помочь

  • 0
    Я люблю это решение. Как бы то ни было, он не «группирует» закрытые дни. То есть, он получает 3 значения в массиве, когда должно быть 2 значения; «dayTo» должно быть «воскресенье» в «субботу». В противном случае это блестяще.
  • 0
    Мой тестовый прогон дал dayTo «воскресенье» в «субботу» из вашего опубликованного массива.
Показать ещё 1 комментарий
1

Это сложно, но не так невозможно (и помните, что это нечто вроде слияния, а не сортировки):

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню