在PHP中按键功能对数组进行排序

时间:2018-07-23 15:00:41

标签: php sorting

是否可以通过键函数的返回值对PHP数组进行排序?像Python的sorted(arr, key=keyfn)或Clojure的(sort-by keyfn arr)一样,

usort($array, function ($a, $b) {
     $key_a = keyfn($a);
     $key_b = keyfn($b);
     if ($key_a == $key_b) return 0;
     if ($key_a < $key_b) return -1;
     return 1;
});

可以满足我的要求,但是它很冗长,它比实际需要的时间更频繁地调用keyfn(可能很慢)

2 个答案:

答案 0 :(得分:1)

一些简单的代码,用于缓存predicate的结果和排序(使用spaceship运算符可减少返回0,1,-1的行)。如果predicate的结果为int,则您甚至可以返回$key_a - $key_b

$array = [2,2,2,1,1,0,0,8];
$values_cache = [];
usort($array, function ($a, $b) use (&$values_cache) {
    $key_a = isset($values_cache[$a]) ? $values_cache[$a] : ($values_cache[$a] = keyfn($a));
    $key_b = isset($values_cache[$b]) ? $values_cache[$b] : ($values_cache[$b] = keyfn($b));
    return $key_a <=> $key_b;
});
echo '<pre>', print_r($array), '</pre>';

function keyfn($v) {
    echo 'call a keyfn' . PHP_EOL;
    return 2 * $v;
}

简单的小提琴https://3v4l.org/W1N7Y

答案 1 :(得分:1)

我最终以这种方式实现了它:

function sort_by($key_f, $arr) {
    $values = array_map($key_f, $arr);
    asort($values);
    $sorted_arr = array();

    foreach ($values as $idx => $value) {
        $sorted_arr[] = $arr[$idx];
    }

    return $sorted_arr;
}