2012-06-19 31 views
7

我有以下陣列:排序陣列在array_multisort

$array = array(
     'note' => array(), 
     'year' => array('2011','2010', '2012'), 
     'type' => array('conference', 'journal', 'conference'), 
    ); 

我使用下面的函數使用的字段類型和另一個數組的數組進行排序:

function array_multisort_by_order(array $array, $by, array $order) 
{ 
    $order = array_flip($order); 
    $params[] = $array[$by]; 
    foreach($params[0] as &$v) $v = $order[$v]; 
    foreach($array as &$v) $params[] = &$v; unset($v); 
    call_user_func_array('array_multisort', $params); 
    return $array; 
} 

當我撥打以下功能我得到以下錯誤:

$array = array_multisort_by_order($array, 'type', array('conference', 'journal')); 

print_r($array['type']); 

錯誤:

Warning: array_multisort(): Array sizes are inconsistent. 

我知道數組是不一致的。有更好的功能使用嗎?

請檢查:codepad

所需的輸出:

Array 
(
[note] => Array 
    (
     [0] => 
     [1] => 
     [2] => 
    ) 

[year] => Array 
    (
     [0] => 2011 
     [1] => 2012 
     [2] => 2010 
    ) 

[type] => Array 
    (
     [0] => conference 
     [1] => conference 
     [2] => journal 
    ) 

) 

實施例2:

陣列

$array = array(
     'note' => array([0]=>'test1', [1]=>'test2'), 
     'year' => array([0]=>'2011', [2]=>'2012'), 
     'type' => array([0]=>'conference',[1]=>'journal', [2]=>'conference'), 
    ); 

所需的結果2

Array 
(
[note] => Array 
    (
     [0] => test1 
     [1] => 
     [2] => tes2 
    ) 

[year] => Array 
    (
     [0] => 2011 
     [1] => 2012 
     [2] => 
    ) 

[type] => Array 
    (
     [0] => conference 
     [1] => conference 
     [2] => journal 
    ) 

) 

感謝

+3

嗯,所需的輸出會使事情從代碼中找到更明確的答案。你能提供嗎? – Wrikken

+0

添加了期望的輸出! – glarkou

+0

好的,剩下的1個問題:子陣列總是空或長度一致,或者我們可以期望在這裏有2個子項目的子陣列,如果是的話,我們如何處理?假設它們仍然與其他子陣列中的前兩項匹配? – Wrikken

回答

3

OK,所以,想到的第一個解決方案之一是增加在空值,以使它們保持一致:

function array_multisort_by_order(array $array, $by, array $order) 
{ 
    $max = max(array_map('count',$array)); 
    //or, alternatively, depending on input (if there are no 'complete' subarrays): 
    //$max = max(array_map(function($arr){return max(array_keys($arr));},$array))+1; 

    //ADDITION: negative numeric keys: 
    $min = min(array_map(function($arr){return min(array_keys($arr));},$array)); 
    $width = $max - min(0,$min); 

    foreach($array as &$sub){ 
     // $addin = array_diff_key(array_fill(0,$max,null),$sub); 
     // $addin changed for negative keys: 
     $addin = array_diff_key(array_combine(range($min,$max),array_fill(0,$width,null)),$sub); 
     $sub = $addin + $sub; 
     ksort($sub); 
    } 
    $order = array_flip($order); 
    $params[] = $array[$by]; 
    foreach($params[0] as &$v) $v = $order[$v]; 
    foreach($array as &$v) $params[] = &$v; unset($v); 
    call_user_func_array('array_multisort', $params); 
    //no closeures here: 
    //foreach($array as &$sub) $sub = array_filter(function($a){return !is_null($a);},$sub); 
    $filter = create_function('$a','return !is_null($a);'); 
    foreach($array as &$sub) $sub = array_filter($sub,$filter); 
    return $array; 
} 
+0

是的,我有這個想法。我做了http://codepad.org/4QcAoemv,但實際上並沒有將鍵添加到原始數組中。另外還有一種方法可以在執行multisort之後擺脫這些「空」值嗎? – glarkou

+0

呃,鍵盤正在運行<5.3,不能使用閉包......類似這樣的你的意思是:http://codepad.org/5kMHlRc6 – Wrikken

+0

是的,這將完成這項工作。如果你可以檢查代碼,我嘗試使用一個更簡單的方法來填充缺少的鍵'foreach($ array ['type'] as $ k => $ v){foreach($ array as $ element => $ a){ $ iterator = $ array [$ element]; if(!isset($ iterator [$ k])){iterator [$ key] =''; } } }'。這是臨時填充'$ iterator'數組而不是原始數組。再次感謝您的幫助,我將使用您的解決方案。我將其標記爲正確。你能編輯你的答案嗎? – glarkou