Using a Static Class Method to *Quickly* Sort an Array By Key Value in PHP

两盒软妹~` 提交于 2020-01-05 08:33:56

问题


This question is different than others, as it's focus is on sorting an array with a static class method rather than the typical procedural approach.

I am look for a very performant way to implement the function sortByKeyValue below. Other somewhat related answers are focused on getting the job done, this question is more about getting the job done and getting it done very quickly (as a static method).

Anyone want to take a crack at it? I'll probably throw some bounty on this question to squeeze out the performance junkies. :)

<?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"}]
?>

回答1:


I ran the following to compare the speed of multisort, a pre-PHP 5.3 method, with a more modern method that uses usort with a closure function:

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

As you can see, the old method was more than twice as fast:

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

So here's how I would do the class:

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;
    }

}



回答2:


You can use usort with a closure (Available php 5.3+)

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

Pre 5.3 you would have to create a sorter function and pass to usort

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

Or you can place the arraySorter as a static method on your class

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

Note. This will perform an in place sort.

As Suggested by @Kirk in comments you can use a function to return an anonymous sorter function so the implementation isn't bound to the name property

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

Then you can call

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



回答3:


I prefer 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>';


来源:https://stackoverflow.com/questions/17707150/using-a-static-class-method-to-quickly-sort-an-array-by-key-value-in-php

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!