多次在同一个数组上使用array_multisort?

时间:2009-03-30 07:47:08

标签: php arrays sorting multidimensional-array

我从我的数据库中提取了大量的数据表(大约1500行,每行有10-15个字段),我正在做一些过滤器并生成一些统计数据并将这些数据存储在excel电子表格中供用户使用下载。

不是一遍又一遍地使用相同的相当复杂的查询来打击数据库而只需要很小的修改(对WHERE和ORDER BY),我正在做一次数据库之旅,将结果放入一个大数组,然后使用array_filterarray_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 个答案:

答案 0 :(得分:1)

这就是我最终的目标。这是由martin在PHP手册中的usort页面的评论中发布的功能的略微修改版本。

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