2013-07-17 26 views
1

此問題與其他問題不同,因爲它的焦點是使用靜態類方法而不是典型的過程方法對數組進行排序。使用靜態類方法*快速*按PHP中的鍵值排序數組

我正在尋找一種非常高效的方式來實現下面的函數sortByKeyValue。其他相關的答案都集中在完成工作上,這個問題更多的是完成工作並以非常快的速度完成工作(作爲一種靜態方法)。

任何人都想對其進行破解?我可能會在這個問題上拋出一些慷慨的東西來擠出表演愛好者。 :)

<?php 

$data = array(
    array('name' => 'B', 'cheesy' => 'bacon'), 
    array('name' => 'C', 'delicious' => 'tacos'), 
    array('name' => 'A', 'lovely' => 'viddles'), 
); 

class MyArray { 

    public static function sortByKeyValue($array, $key, $direction = 'ASC') { 
     // Do the thing 
     // Help me! 

     return $array; 
    } 

} 

$data = MyArray::sortByKeyValue($data, 'name'); 

// Should output the name key in order 
// I am not including the garbage keys I threw in, but they should be there too) 
// [{"name": "A"},{"name": "B"},{"name": "C"}] 
?> 
+0

@insertusername此處更新了問題以反映多個密鑰 –

回答

1

我跑了以下比較multisort,一個PHP 5.3以前的方法,與一個更現代的方法,使用usort與關閉功能的速度:

$alpha = 'abcdefghijklmnopqrstuvwxyz'; 
$cnt = 1000; 
$key = 'name'; 
$direction = 'ASC'; 
$array = array(); 
for ($i=0; $i<$cnt; $i++){ 
    $array[$i]['name'] = substr(str_shuffle($alpha), 0, 8); 
    $array[$i]['job'] = substr(str_shuffle($alpha), 0, 8); 
} 
$pre = $array;//the test dummies 

//PRE-PHP 5.3 

$t[0] = -microtime(); 
$sub = array(); 
foreach ($pre as $item) { 
     $sub[] = $item[$key]; 
} 
if ($direction == 'ASC') $ord = SORT_ASC; 
else $ord = SORD_DESC; 
array_multisort($sub, $ord, $pre); 
$t[0] += microtime(); 

//USORT WITH CLOSURE 

$t[1] = -microtime(); 
usort($array, function ($a, $b) use($key, $direction){ 
    if ($direction == 'ASC'){ 
     return strcmp($a[$key], $b[$key]); 
    } 
    return strcmp($b[$key], $a[$key]); 
}); 
$t[1] += microtime(); 
var_dump($t); 

正如你所看到的,舊的方法快一倍以上:

Array 
(
    [0] => 0.005 
    [1] => 0.014001 
) 

因此,這裏是我會怎麼做的類:

class MyArray { 

    public static function sortByKeyValue($array, $key, $direction = SORT_ASC) { 
     $sub = array(); 
     foreach ($array as $item) { 
      $sub[] = $item[$key]; 
     } 
     array_multisort($sub, $direction, $array); 
     return $array; 
    } 

} 
+0

這真是太棒了。 –

3

可以使用usort與閉合(可用的PHP 5.3+)

usort($array, function($a, $b){ return strcmp($a["name"], $b["name"]);}); 

5.3前你必須創建一個分揀功能,並傳遞給usort

function arraySorter($a, $b){ 
    return strcmp($a["name"], $b["name"]); 
} 
usort($array, "arraySorter"); 

或者您可以將arraySorter作爲靜態方法放置在您的課堂上

public static function _arraySorter($a, $b){ 
    return strcmp($a["name"], $b["name"]); 
} 
// then call 
usort($array, array("MyArray", "_arraySorter")); // for static 

注意。這將執行到位排序。

正如意見建議由@Kirk你可以使用函數返回一個匿名分揀功能,因此執行不綁定到name屬性

function getSorter($property){ 
     return function($a, $b) use ($property){ 
      return strcmp($a[$property], $b[$property]); 
     }; 
} 

然後就可以調用

usort($array, getSorter("name")); 
+0

您將如何實施t在5.3之前使用靜態類嗎? –

+1

@Kirk通過將其封裝在一個靜態方法中或將數組作爲數組傳遞給數組'array($ this,$ method)' –

+0

如何使它成爲動態的,所以「name」在arraySorter方法中沒有被硬編碼? –

1

我喜歡array_multisort()

<?php 
$data = array(
    array('name' => 'B', 'cheesy' => 'bacon'), 
    array('name' => 'C', 'delicious' => 'tacos'), 
    array('name' => 'A', 'lovely' => 'viddles'), 
); 

class MyArray { 

    public static function sortByKeyValue($array, $key, $direction = 'ASC') { 

     $tmp = array(); 
     foreach($array as $k=>$r){ 
      $tmp[] = $r[$key]; 
     } 
     array_multisort($tmp,($direction == 'ASC' ? SORT_ASC : SORT_DESC),$array); 

     return $array; 
    } 

} 

$data = MyArray::sortByKeyValue($data, 'name'); 

echo '<pre>',print_r($data),'</pre>';