我正在尝试排序一个多维数组,并始终在数组的末尾有一个值。数组应该按'unitText'排序(不关心unitID是如何排序的),但总是以' Last '作为数组中的最后一个值。我差不多明白了,但还没有完全明白。
<?php
function cmp($a, $b)
{
/*
$a = preg_replace('@^(Last) @', '', $a);
$b = preg_replace('@^(Last) @', '', $b);
return strcasecmp($a, $b);
*/
if(strtolower(substr($a['unitText'],0,4))=="last") return strnatcmp($a['unitText'],9999);
else if(strtolower(substr($b['unitText'],0,4))=="last") return strnatcmp(9999,$b['unitText']);
else return strnatcmp($a, $b);
//return strnatcmp($a['unitText'], $b['unitText']);
//return end($a) > end($b);
}
$unit = array(
array("unitID"=>80, "unitText"=>"Q701"),
array("unitID"=>30, "unitText"=>"H568"),
array("unitID"=>25, "unitText"=>"Last"),
array("unitID"=>40, "unitText"=>"Z255"),
array("unitID"=>20, "unitText"=>"A459")
);
echo "<pre>";
print_r($unit);
echo "</pre>";
echo "<hr/>";
//uksort($unit['unitText'], "cmp");
//array_multisort($unit['unitText'], SORT_DESC, $unit['unitID'], SORT_ASC, $unit);
usort($unit, 'cmp');
echo "<pre>";
print_r($unit);
echo "</pre>";
?>
应该以:
结尾Array
(
[0] => Array
(
[unitID] => 20
[unitText] => A459
)
[1] => Array
(
[unitID] => 30
[unitText] => H568
)
[2] => Array
(
[unitID] => 80
[unitText] => Q701
)
[3] => Array
(
[unitID] => 40
[unitText] => Z255
)
[4] => Array
(
[unitID] => 25
[unitText] => Last
)
)
我做错了什么?
你的问题是这一行:
else return strnatcmp($a, $b);
请记住,$a
和$b
都是数组,但strnatcmp()
比较字符串。当调用这个函数时,您的两个数组将隐式转换为字符串,它们的值都为Array
,因此它们将返回相等的值,并且不会排序。
你应该比较unitText
的值:
else return strnatcmp($a['unitText'], $b['unitText'])
你没有看到这一点的事实告诉我,你没有把error_reporting
级别设置得足够高,因为当它发生时,隐式强制转换会发出E_NOTICE
。在开发中,您应该始终设置error_reporting(E_ALL | E_STRICT);
(无论是在代码的入口点,还是在您的php.ini
中,等等),以便任何小问题都可以立即标记出来供您修复。
同样,当其中一个值是'Last'时,你根本没有理由调用strnatcmp()
,因为你已经知道这个值应该是最后一个。只需返回1
或-1
(取决于哪个包含'Last')并完成它。
最后,代码中不需要所有的else
条件。由于所有路径都会发出return
,因此可以假设if
块之后的任何内容仅在比较失败时才会执行:
if (strtolower(substr($a['unitText'],0,4))=="last") {
return 1;
}
if strtolower(substr($b['unitText'],0,4))=="last") {
return -1;
}
return strnatcmp($a['unitText'], $b['unitText']);
在上面的例子中,第二个if
只有在我们没有在$a
中找到'Last'时才会执行,因为如果它找到了,函数就已经结束了。类似地,最后的return
语句(带有strnatcmp()
调用)只有在上述if
条件都不通过的情况下才会执行,因为它们中的任何一个都将返回一个值并结束函数。
这是一件小事,但是嵌套一堆不需要的if
和else
块会降低代码的可读性。
最后比较a和b,它们都是数组。我得到PHP警告:
PHP [Warning] strnatcmp()期望参数1是字符串,数组给定
所有的比较都可以简化如下:
if(strtolower(substr($a['unitText'],0,4))=="last") return 1;
else if(strtolower(substr($b['unitText'],0,4))=="last") return -1;
else return strnatcmp($a['unitText'], $b['unitText']);
你只需要返回0,大于或小于0。