2012-07-30 61 views
1

我有排序方向的问题。我尝试用方向对多维数组进行排序。我不能直接使用array_multisort(),因为我不知道会有多少参数。我使用call_user_func_array('array_multisort', $params);它可以工作,但我无法设置排序方向(SORT_ASC,SORT_DESC)。我如何设置call_user_func_array('array_multisort', $params);的排序方向? 这里是我的代码,你可以尝试call_user_func_array array_multisort

function get_fields($data, $order_by) { 
    $order_row = preg_split("/[\s,]+/", $order_by); 
    for ($i=0;$i<count($order_row);$i++) { 
     foreach ($data as $key => $row) { 
      $tmp[$i][$key] = $row[$order_row[$i]];  
     } 
    } 
    return $tmp; 
} 

function ordering($data, $order_by) { 
    $tmp = get_fields($data, $order_by); 
    $params = array(); 
    foreach($tmp as &$t){ 
     $params[] = &$t; 
    } 

    $params[1] = array("SORT_DESC","SORT_DESC","SORT_DESC","SORT_DESC"); // like that no warning but no sorting 

    $params[] = &$data; 
    call_user_func_array('array_multisort', $params); 
    return array_pop($params); 
} 

$data = array (
    array('id' => 1,'name' => 'Barack','city' => 9), 
    array('id' => 7,'name' => 'boris','city' => 2), 
    array('id' => 3,'name' => 'coris','city' => 2), 
    array('id' => 3,'name' => 'coris','city' => 2) 
); 

$order_by = "city desc, name"; 

echo "<br>ORDER BY $order_by<br>"; 
$ordered = ordering($data, $order_by); 
echo "<pre>"; 
var_dump($ordered); 
echo "</pre>"; 

我想要做一个排序,如MySQL ORDER BY city DESC, name。这是我的目标。

回答

1

我有同样的问题一次排序。看来call_user_func_array()不能处理常量。 我已经通过动态地建立一个参数字符串和评估此字符串解决了这个问题:

$args = array($arr1, $arr2); 
$order = array(SORT_ASC, SORT_DESC); 
$evalstring = ''; 

foreach($args as $i=>$arg){ 
    if($evalstring == ''){ $evalstring.= ', '; } 
    $evalstring.= '$arg'; 
    $evalstring.= ', '.$order[$i]; 
} 
eval("array_multisort($evalstring);"); 

我知道的eval()是邪恶的,这不是一个干净的方式,但它工作;-)

0

为了能够多次对数组进行排序并获得类似ORDER BY city DESC, name ASC的结果,您需要一个可以执行stable sort的函数。
据我知道PHP没有一个,所以你必须用一个比较功能这样

$data = array (
    array('id' => 3,'name' => 'coris','city' => 2), 
    array('id' => 1,'name' => 'Barack','city' => 9), 
    array('id' => 7,'name' => 'boris','city' => 2), 
    array('id' => 3,'name' => 'coris','city' => 2), 
); 

$order_by = array(
    'city' => array('dir' => SORT_DESC, 'type' => SORT_NUMERIC), 
    'name' => array('dir' => SORT_ASC, 'type' => SORT_STRING), 
); 

function compare($row1,$row2) { 
    /* this function should determine which row is greater based on all of the criteria 
     and return a negative number when $row1 < $row2 
        a positive number when $row1 > $row2 
        0 when $row1 == $row2 
    */ 

    global $order_by; 

    foreach($order_by as $field => $sort) { 
     if($sort['type'] != SORT_NUMERIC) { 
      // strings are compared case insensitive and assumed to be in the mb_internal_encoding 
      $cmp = strcmp(mb_strtolower($row1[$field]), mb_strtolower($row2[$field])); 
     } else { 
      $cmp = doubleval($row1[$field]) - doubleval($row2[$field]); 
     } 
     if($sort['dir'] != SORT_ASC) $cmp = -$cmp; 
     if($cmp != 0) return $cmp; 
    } 
    return 0; 
} 


usort($data,'compare');