使用自定义排序顺序排序数组,最后一个值



我正在尝试排序一个多维数组,并始终在数组的末尾有一个值。数组应该按'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条件都不通过的情况下才会执行,因为它们中的任何一个都将返回一个值并结束函数。

这是一件小事,但是嵌套一堆不需要的ifelse块会降低代码的可读性。

最后比较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。

相关内容

  • 没有找到相关文章

最新更新