1

我有一个数组:

$a = array("Freshman Spring" => 3, "Freshman Winter" => 2, "Freshman Summer" => 4, "Freshman Fall" => 1); 

每个学年会有不同的数组,但没有数组会混合 fre、soph 等年份。

我的问题是我需要按照学校的季节(秋季、冬季、春季、夏季)对这个数组进行排序。我尝试使用 uksort 但我的代码实际上什么也没做,因为无论如何它都会以相同的方式排序。

function cmp($a, $b) {
    $a = preg_replace('@^(freshman|sophomore|junior|senior) @', '', $a);
    $b = preg_replace('@^(freshman|sophomore|junior|senior) @', '', $b);
    return strcasecmp($a, $b);
}

uksort($a, "cmp");

我明白了:

Array
(
    [Freshman Fall] => 1
    [Freshman Spring] => 3
    [Freshman Summer] => 4
    [Freshman Winter] => 2
)

但需要得到这个:

Array
(
    [Freshman Fall] => 1
    [Freshman Winter] => 2
    [Freshman Spring] => 3
    [Freshman Summer] => 4
)

uksort 是要走的路吗?我做错了什么?请记住,数组值不会是那些值,它们将保存对象。非常感谢任何和所有帮助!

4

4 回答 4

1

为什么不使用值作为键 {1,2,3,4} 并将“对象”存储为值。让排序变得非常容易......

如果您想要漂亮的名称,您始终可以将 {1,2,3,4} 映射到定义或类常量。

于 2012-08-13T21:09:35.787 回答
1

你真的很亲近。实际上, uksort 正在做你要求它做的事情,去掉等级名称,并按第二个单词的字母顺序排序。你需要它做的有点不同——你要求它按季节排序。您将不得不根据您想要查看的排序顺序为它们编写自己的比较。您可以使用 mr-sk 给出的解决方案,也可以执行以下操作:

function cmp($a, $b) {
    $a = preg_replace('@^(freshman|sophomore|junior|senior) @', '', $a);
    $b = preg_replace('@^(freshman|sophomore|junior|senior) @', '', $b);
    $seasons = array("FALL"=>0, "WINTER"=>1, "SPRING"=>2, "SUMMER"=>3);
    return $seasons[strtoupper($a)]-$seasons[strtoupper($b)];
}

此外,您可以将您的正则表达式(如果您确定只会在开头得到这些词)更改为

/^\w* /

享受!

于 2012-08-13T21:19:48.963 回答
1

您的代码失败,因为您仅在季节上执行 strcasecmp() - 换句话说,您正在按字母顺序排列季节,这就是您的结果显示的内容。您需要按定义的顺序进行排序。

我会这样做,将季节转换为预先分配的数字:

function cmp($a, $b) {
    $seasons = array('Fall'=>1, 'Winter'=>2, 'Spring'=>3, 'Summer'=>4);
    $aParts = explode(' ', $a);
    $bParts = explode(' ', $b);

    $a = $seasons[$aParts[1]];
    $b = $seasons[$bParts[1]]

    return $b - $a;
}

如果你想包括这些类:

function cmp($a, $b) {
    $classes = array('Freshman'=>1, 'Sophomore'=>2, 'Junior'=>3, 'Senior'=>4);
    $seasons = array('Fall'=>1, 'Winter'=>2, 'Spring'=>3, 'Summer'=>4);
    list($aClass, $aSeason) = explode(' ', $a);
    list($bClass, $bSeason) = explode(' ', $b);
    $aNum = 10*$classes[$aClass] + $seasons[$aSeason];
    $bNum = 10*$classes[$bClass] + $seasons[$bSeason];

    return $bNum - $aNum;           
}
于 2012-08-13T21:23:46.980 回答
-1

您正在按键排序,而不是按值排序。如果你按键排序,你会得到秋天 < 春天 < 夏天 < 冬天。

只需使用

asort($a);

这将按值 (1,2,3,4) 排序,但保留关键相关性。

于 2012-08-13T21:19:00.350 回答