Использование array_multisort для одного и того же массива несколько раз? - PullRequest
2 голосов
/ 30 марта 2009

У меня есть большая таблица данных, извлеченная из моей базы данных (~ 1500 строк, каждая с 10-15 полями), и я делаю несколько фильтров и генерирую некоторые статистические данные и сохраняю их в электронной таблице Excel, чтобы пользователь мог скачать.

Вместо того, чтобы снова и снова попадать в базу данных с одним и тем же довольно сложным запросом с небольшими изменениями (к WHERE и ORDER BY), я совершаю одну поездку в БД, помещая результаты в один большой массив и затем используя array_filter и array_multisort, чтобы получить мои новые представления данных.

Я новичок в array_multisort, поэтому я опубликую то, что я сделал здесь для критики.

// an numerical array of associative arrays
$records = $dbResult->convertToArray();

$fields = $dbResult->getFieldNames();

// this is run once at the start
$sortArr = array();
foreach ($fields as $field) $sortArr[$field] = array();

foreach ($records as $r) {
    foreach ($r as $key => $value) {
        $sortArr[$key][] = $value;
    }
}

// and then to sort:
array_multisort(
    $sortArr['Date Completed'], SORT_DESC,
    $sortArr['Last Name'], SORT_ASC,
    $sortArr['First Name'], SORT_ASC,
    $sortArr['Course'], SORT_ASC,
    $records
);

Это прекрасно работает, хотя первоначальное "копирование всего результата в другой массив" мне кажется странным. Проблема возникает, когда мне нужно снова отсортировать список. У меня такое ощущение, что мой $sortArr должен синхронизироваться с массивом $records, но он ломается после каждой сортировки.

Я даже не уверен, что это целевое использование array_multisort, так что я могу быть далеко не в курсе. Кто-нибудь может дать какой-нибудь совет или совет? Как вы сортируете многомерные массивы?

1 Ответ

1 голос
/ 30 марта 2009

Вот что я закончил. Это слегка измененная версия функции, опубликованная Мартином в комментариях на странице usort в руководстве по PHP.

function arfsort( &$array, $fieldList ){
    if (!is_array($fieldList)) {
        $fieldList = array(array($fieldList, SORT_ASC));
    } else {
        for ($i = 0; $i < count($fieldList); ++$i) {
            if (is_array($fieldList[$i])) {
                if (!isset($fieldList[$i][1])) $fieldList[$i][1] = SORT_ASC;
            } else {
                $fieldList[$i] = array($fieldList[$i], SORT_ASC);
            }
        }
    }
    $GLOBALS['__ARFSORT_LIST__'] = $fieldList;
    usort( $array, 'arfsort_func' );

}

function arfsort_func( $a, $b ){
    foreach( $GLOBALS['__ARFSORT_LIST__'] as $f ) {
        $strc = strcasecmp($b[$f[0]], $a[$f[0]]);
        if ( $strc != 0 ){
            return $strc * (!empty($f[1]) && $f[1] == SORT_DESC ? 1 : -1);
        }
    }
    return 0;
}

Надеюсь, я сделал функцию немного более надежной, чем оригинальное решение. Использование:

arfsort($my2DArray, "id");  // just sort by the id field, ascending
// sort by these lastName then firstName, ascending
arfsort($my2DArray, array("lastName", "firstName"));

arfsort($my2DArray, array(
    array("date", SORT_DESC),    // sort by date DESC
    array("lastName", SORT_ASC), // then by last name ascending
    array("firstName"),          // SORT_ASC is the default
    "middleInitial"              // and you don't need to wrap stuff in an array.
));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...