php array_multisort () по 2 полям - PullRequest
       0

php array_multisort () по 2 полям

1 голос
/ 03 ноября 2011

Я использую функцию array_multisort () для сортировки массива по значению поля. что мне нужно, это отсортировать его по 2 значениям поля, по дате и по времени. Вот структура массива:

Array
(
    [0] => Array
        (
            [id_art] => 5292
            [free_art] => 0
            [apero_art] => 0
            [name_cat] => Teatro
            [date_dat] => 2010-11-24
            [date2_dat] => 0000-00-00
            [name_spa] => Cinema Teatro
            [title_int] => Il piacere dell'onestà 
            [id_cat] => 2
            [time_tim] => 20:30:00
            [intro_int] => Una produzione Teatro Eliseo di Roma - ChiassoCultura 
            [image_art] => noimage.png
        )

    [1] => Array
        (
            [id_art] => 4983
            [free_art] => 0
            [apero_art] => 0
            [name_cat] => Cinema
            [date_dat] => 2011-04-20
            [date2_dat] => 2011-04-20
            [name_spa] => Cinema Morettina
            [title_int] => Inland Empire
            [id_cat] => 1
            [time_tim] => 20:30:00
            [intro_int] => Rassegna dedicata a David Lynch
            [image_art] => noimage.png
        )

    [2] => Array
        (
            [id_art] => 4983
            [free_art] => 0
            [apero_art] => 0
            [name_cat] => Cinema
            [date_dat] => 2011-04-22
            [date2_dat] => 2011-04-22
            [name_spa] => Cinema Iride
            [title_int] => Inland Empire
            [id_cat] => 1
            [time_tim] => 17:00:00
            [intro_int] => Rassegna dedicata a David Lynch
            [image_art] => noimage.png
        )....

Что я делаю сейчас:

function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
    $sort_col = array();
    foreach ($arr as $key=> $row) {
        $sort_col[$key] = $row[$col];
    }
    array_multisort($sort_col, $dir, $arr); 
}

Как мне легко сделать за один раз двойную сортировку?

Спасибо.

Ответы [ 2 ]

5 голосов
/ 03 ноября 2011

Если я понимаю, что вам нужно сделать, вы можете использовать usort:

usort($array, function($a, $b) {
    if ($a['date_cat'] > $b['date_cat']) return 1;
    if ($a['date_cat'] < $b['date_cat']) return -1;
    if ($a['time_tim'] > $b['time_tim']) return 1;
    if ($a['time_tim'] < $b['time_tim']) return -1;        
    return 0;
});

Мне кажется, что ваша функция работает немного извращенно.Вы извлекаете столбец вашего массива, чтобы создать массив для сортировки, связанный с исходным массивом.Потребовалось несколько чтений и проверка php вручную, чтобы понять ваш код (слишком плохо), вы должны (для меня) отключить создание массива index в другую функцию, прежде чем вызывать сортировку.

Если вам нужен динамический выбор столбцов, возможно, вы можете использовать замыкания (PHP 5.3+?):

function your_sort($orderby, $array) {
    return usort($array, function ($a, $b) use ($orderby) {
        foreach($orderby as $field) {
            if ($a[$field] > $b[$field]) return 1;
            if ($a[$field] < $b[$field]) return -1;
        }
        return 0;
    });
}

И затем вы можете вызвать функцию следующим образом:

your_sort(array('date_cat','time_tim'), $array);
0 голосов
/ 05 мая 2012

Используя некоторый код из комментария php.net и других настроек, я написал функцию, которая принимает эти аргументы:

  1. $ a = массив
  2. $ orderby = строка заказа, написанная на языке sql
  3. $ children_key = имя возможного столбца , в котором возможный дочерний узел сохраняется

Здесь функция:

function array_multiorderby( $data, $orderby, $children_key=false )
{
    // parsing orderby
    $args = array();
    $x = explode( ' ', str_replace( ',', ' ', $orderby ) );
    foreach( $x as $item ) 
    {
        $item = trim( $item );
        if( $item=='' ) continue;
        if( strtolower($item)=='asc' ) $item = SORT_ASC;
        else if( strtolower($item)=='desc' ) $item = SORT_DESC;
        $args[] = $item;
    }

    // order
    foreach ($args as $n => $field) 
    {
        if (is_string($field)) 
        {
            $tmp = array();
            foreach ($data as $key => $row)
            $tmp[$key] = $row[$field];
            $args[$n] = $tmp;
        }
    }
    $args[] = &$data;
    call_user_func_array('array_multisort', $args);
    $data = array_pop($args);

    // order children
    if( $children_key )
    {
        foreach( $data as $k=>$v ) if( is_array($v[$children_key]) ) $data[$k][$children_key] = array_multiorderby( $v[$children_key], $children_key, $orderby );
    }

    // return
    return $data;
}

Применение в вашем конкретном случае:

$array = array_multiorderby( $array, "date_dat DESC, time_tim DESC" );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...