【发布时间】:2011-04-26 17:07:21
【问题描述】:
我找到了一些按值排序的答案,但不是键。
我想做的是反向排序,所以:
$nametocode['reallylongname']='12';
$nametocode['shortname']='10';
$nametocode['mediumname']='11';
我希望它们按这个顺序排列
- 真的很长的名字
- 媒体名称
- 短名称
中间名短名
非常感谢
【问题讨论】:
我找到了一些按值排序的答案,但不是键。
我想做的是反向排序,所以:
$nametocode['reallylongname']='12';
$nametocode['shortname']='10';
$nametocode['mediumname']='11';
我希望它们按这个顺序排列
中间名短名
非常感谢
【问题讨论】:
要绝对使用 uksort,您可以这样做:
$nametocode['reallylongname']='12';
$nametocode['name']='17';
$nametocode['shortname']='10';
$nametocode['mediumname']='11';
uksort($nametocode, function($a, $b) {
return strlen($a) - strlen($b);
});
array_reverse($nametocode, true);
输出:
Array
(
[reallylongname] => 12
[mediumname] => 11
[shortname] => 10
[name] => 17
)
我已经测试了这段代码。
【讨论】:
在 PHP7+ 中,您可以将uksort() 与太空船运算符和匿名函数一起使用,如下所示:
uksort($array, function($a, $b) {
return strlen($b) <=> strlen($a);
});
【讨论】:
下面的代码使用 lambda 函数按键的字符串长度,然后按区分大小写的键本身对 PHP 哈希数组进行排序,均按升序排列:
uksort($yourArray, function ($a, $b) {
return (strlen($a) == strlen($b) ? strcmp($a, $b) : strlen($a) - strlen($b));
});
此代码以相反的顺序执行相同的操作:
uksort($yourArray, function ($b, $a) {
return (strlen($a) == strlen($b) ? strcmp($a, $b) : strlen($a) - strlen($b));
});
【讨论】:
根据长度对键进行排序的一个限制是:相等长度的键不会重新排序。假设我们需要在descending order 中按长度对密钥进行排序。
$arr = array(
"foo 0" => "apple",
"foo 1" => "ball",
"foo 2 foo 0 foo 0" => "cat",
"foo 2 foo 0 foo 1 foo 0" => "dog",
"foo 2 foo 0 foo 1 foo 1" => "elephant",
"foo 2 foo 1 foo 0" => "fish",
"foo 2 foo 1 foo 1" => "giraffe"
);
debug($arr, "before sort");
$arrBad = $arr;
sortKeysDescBAD($arrBad);
debug($arrBad, "after BAD sort");
sortKeysDescGOOD($arr);
debug($arr, "after GOOD sort 2");
function sortKeysDescBAD(&$arrNew) {
$arrKeysLength = array_map('strlen', array_keys($arrNew));
array_multisort($arrKeysLength, SORT_DESC, $arrNew);
//return max($arrKeysLength);
}
function sortKeysDescGOOD(&$arrNew) {
uksort($arrNew, function($a, $b) {
$lenA = strlen($a); $lenB = strlen($b);
if($lenA == $lenB) {
// If equal length, sort again by descending
$arrOrig = array($a, $b);
$arrSort = $arrOrig;
rsort($arrSort);
if($arrOrig[0] !== $arrSort[0]) return 1;
} else {
// If not equal length, simple
return $lenB - $lenA;
}
});
}
function debug($arr, $title = "") {
if($title !== "") echo "<br/><strong>{$title}</strong><br/>";
echo "<pre>"; print_r($arr); echo "</pre><hr/>";
}
输出将是:
before sort
Array
(
[foo 0] => apple
[foo 1] => ball
[foo 2 foo 0 foo 0] => cat
[foo 2 foo 0 foo 1 foo 0] => dog
[foo 2 foo 0 foo 1 foo 1] => elephant
[foo 2 foo 1 foo 0] => fish
[foo 2 foo 1 foo 1] => giraffe
)
after BAD sort
Array
(
[foo 2 foo 0 foo 1 foo 0] => dog
[foo 2 foo 0 foo 1 foo 1] => elephant
[foo 2 foo 0 foo 0] => cat
[foo 2 foo 1 foo 0] => fish
[foo 2 foo 1 foo 1] => giraffe
[foo 0] => apple
[foo 1] => ball
)
after GOOD sort
Array
(
[foo 2 foo 0 foo 1 foo 1] => elephant
[foo 2 foo 0 foo 1 foo 0] => dog
[foo 2 foo 1 foo 1] => giraffe
[foo 2 foo 1 foo 0] => fish
[foo 2 foo 0 foo 0] => cat
[foo 1] => ball
[foo 0] => apple
)
注意elephant 和dog 例如(或其他)在两种排序方法中的顺序。第二种方法看起来更好。可能有更简单的方法来解决这个问题,但希望这对某人有所帮助......
【讨论】:
我已经对一些排序算法进行了基准测试,因为性能对我的项目很重要 - 这是我发现的(平均结果运行 1000 倍,排序字段有 cca 300 个元素,键大小为 3-50 个字符):
有时简单的 foreach 仍然会获胜。 显然,使用动态 PHP 功能会降低性能。
【讨论】:
看看我强大的内联方法。为后代保留全球空间!
uksort($data, create_function('$a,$b', 'return strlen($a) < strlen($b);'));
【讨论】:
一个简单的问题需要一个简单的解决方案;-)
arsort($nametocode, SORT_NUMERIC);
$result = array_keys($nametocode);
【讨论】:
使用array_multisort的另一种解决方案:
$keys = array_map('strlen', array_keys($arr));
array_multisort($keys, SORT_DESC, $arr);
这里$keys 是$arr 的键长度的数组。该数组按降序排序,然后使用array_multisort 对$arr 的值进行排序。
【讨论】:
uksort() 有性能优势?
基于@thetaiko 的回答,回调更简单:
function sortByLengthReverse($a, $b){
return strlen($b) - strlen($a);
}
uksort($nametocode, "sortByLengthReverse");
【讨论】:
您可以使用用户定义的键排序函数作为uksort 的回调:
function cmp($a, $b)
{
if (strlen($a) == strlen($b))
return 0;
if (strlen($a) > strlen($b))
return 1;
return -1;
}
uksort($nametocode, "cmp");
foreach ($nametocode as $key => $value) {
echo "$key: $value\n";
}
快速说明 - 要反转排序只需切换“1”和“-1”。
【讨论】:
看看uksort。
【讨论】: