2012-07-30 60 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');