是否可以通过键函数的返回值对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
(可能很慢)
答案 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;
}