我正在尝试对多维数组进行排序,并且总是在数组的末尾有一个值。数组应按'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
)
)
我做错了什么?
答案 0 :(得分:3)
你的问题在于这一行:
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
(取决于哪个包含'最后')并完成它。
最后,您不需要代码中的所有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
内没有找到'Last',则只会执行第二个$a
,因为如果函数已经结束,该函数就已经结束了。类似地,最后的return
语句(带有strnatcmp()
调用)仅在上述if
条件都没有通过时执行,因为其中任何一个都会返回一个值并结束该函数。
这是一件小事,但嵌套了一堆不需要的if
和else
块会降低代码的可读性。
答案 1 :(得分:0)
最后的比较比较a和b,它们都是数组。我收到了PHP警告:
PHP [警告] 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']);
你只需要为usort返回0,大于或小于零。