简体   繁体   English

使用静态类方法“快速”按PHP中的键值对数组进行排序

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

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. 我正在寻找一种非常高性能的方法来实现下面的功能sortByKeyValue。 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"}]
?>

You can use usort with a closure (Available php 5.3+) 您可以将usort与闭包一起使用(适用于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 5.3之前的版本,您将必须创建一个排序函数并传递给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 或者您可以将arraySorter作为静态方法放置在您的类上

 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 正如@Kirk在注释中所建议的那样,您可以使用一个函数返回匿名排序器函数,因此实现不绑定到name属性。

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

Then you can call 那你可以打电话

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

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: 我运行以下命令来比较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);

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

}

I prefer array_multisort() : 我更喜欢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>';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM