如何按值对多维数组进行排序?

7
我是一位有用的助手,能够翻译文本。
我有一个数组,我想按照"attack"键的值对该数组进行排序。数组的前几个键 (15, 13, 18) 是来自数据库中某个特定项目的ID,所以当数组排序时,我不希望这些键被改变。任何帮助都将不胜感激。
这是数组:
$data = array(
    '15' => array(
        'attack' => '45', 'defence' => '15', 'total' => '10'
    ),
    '13' => array(
        'attack' => '25', 'defence' => '15', 'total' => '10'
    ),
    '18' => array(
        'attack' => '35', 'defence' => '15', 'total' => '10'
    )
);
3个回答

18

使用uasort()函数:

此函数使用用户定义的比较函数对数组进行排序,以使数组索引与它们关联的数组元素保持相关。

这主要用于排序关联数组,其中实际元素顺序很重要。

示例:

function cmp($a, $b) {
    if ($a['attack'] == $b['attack']) {
        return 0;
    }
    return ($a['attack'] < $b['attack']) ? -1 : 1;
} 

uasort($data, 'cmp');

如果这些值始终为字符串,您也可以在cmp()函数中使用strcmp()

function cmp($a, $b) {
    return strcmp($a['attack'], $b['attack']);
} 

更新:

要按降序排序,只需更改返回值:

return ($a['attack'] < $b['attack']) ? 1 : -1;
//                                     ^----^

或者采纳 @salathe 的建议:

return $b['attack'] - $a['attack'];

针对过于复杂的回调函数,我们不得不说“Boo”。$a['attack'] - $b['attack']; 就足够了。 - salathe
@salathe:没错,这样会更高效。但这样更符合文档示例的规范。 - Felix Kling
当然,我使用print_r打印数组,但它只在屏幕上打印1。 - Chris Ford
抱歉,是我弄错了。我发现我打印出来的不是那个东西。我还有一个问题:如何按降序排序值? - Chris Ford
感谢您提供的所有答案。 - Chris Ford
显示剩余3条评论

3
只需使用array_multisort即可。
foreach ($data as $key => $row) {
    $attack[$key]  = $row['attack'];
}

// Sort the data with attack descending
array_multisort($attack, SORT_DESC, $data);

更新:
当数组键是字符串时,array_multisort函数可以正常工作,但是在数字数组键的情况下,array_multisort会破坏数组的第一层键。
第一层数组键将被保留。
<?php
$data = array(
    'a' => array(
        'attack' => '45', 'defence' => '15', 'total' => '10'
    ),
    'b' => array(
        'attack' => '25', 'defence' => '15', 'total' => '10'
    ),
    'c' => array(
        'attack' => '35', 'defence' => '15', 'total' => '10'
    )
);
print_r($data);

foreach ($data as $key => $row) {
    $key = (string)$key;
    $attack[$key]  = $row['attack'];
}
print_r($attack);

// Sort the data with attack descending
array_multisort($attack, SORT_DESC, $data);
print_r($data);
?>

输出:

Array
(
    [a] => Array
        (
            [attack] => 45
            [defence] => 15
            [total] => 10
        )

    [b] => Array
        (
            [attack] => 25
            [defence] => 15
            [total] => 10
        )

    [c] => Array
        (
            [attack] => 35
            [defence] => 15
            [total] => 10
        )

)
Array
(
    [a] => 45
    [b] => 25
    [c] => 35
)
Array
(
    [a] => Array
        (
            [attack] => 45
            [defence] => 15
            [total] => 10
        )

    [c] => Array
        (
            [attack] => 35
            [defence] => 15
            [total] => 10
        )

    [b] => Array
        (
            [attack] => 25
            [defence] => 15
            [total] => 10
        )

)

一级数组键不会被保留

<?php
$data = array(
    '15' => array(
        'attack' => '45', 'defence' => '15', 'total' => '10'
    ),
    '13' => array(
        'attack' => '25', 'defence' => '15', 'total' => '10'
    ),
    '18' => array(
        'attack' => '35', 'defence' => '15', 'total' => '10'
    )
);
print_r($data);

foreach ($data as $key => $row) {
    $key = (string)$key;
    $attack[$key]  = $row['attack'];
}
print_r($attack);

// Sort the data with attack descending
array_multisort($attack, SORT_DESC, $data);
print_r($data);
?>

输出:

Array
(
    [15] => Array
        (
            [attack] => 45
            [defence] => 15
            [total] => 10
        )

    [13] => Array
        (
            [attack] => 25
            [defence] => 15
            [total] => 10
        )

    [18] => Array
        (
            [attack] => 35
            [defence] => 15
            [total] => 10
        )

)
Array
(
    [15] => 45
    [13] => 25
    [18] => 35
)
Array
(
    [0] => Array
        (
            [attack] => 45
            [defence] => 15
            [total] => 10
        )

    [1] => Array
        (
            [attack] => 35
            [defence] => 15
            [total] => 10
        )

    [2] => Array
        (
            [attack] => 25
            [defence] => 15
            [total] => 10
        )

)

https://www.php.net/manual/en/language.types.array.php

关键字可以是整数或字符串。值可以是任何类型。
此外,将发生以下关键字转换:
包含有效十进制整数的字符串(除非数字前面有+号)将被转换为整数类型。例如,关键字“8”实际上将存储在8下。另一方面,“08”不会被转换,因为它不是有效的十进制整数。
浮点数也会被转换为整数,这意味着小数部分将被截断。例如,关键字8.7实际上将存储在8下。
布尔值也会被转换为整数,即true关键字实际上将存储在1下,false关键字存储在0下。
null将被转换为空字符串,即null关键字实际上将存储在""下。
数组和对象不能用作关键字。这样做将导致警告:非法偏移类型。

这个答案是不合适/不正确的,因为它破坏了第一层的标识/键。证据:https://phpize.online/s/tt - mickmackusa

-1
$result = [];
foreach ($data as $key => $value) {
    $result[$key] = $value;
    asort($result[$key]);
}
print_r($result);

1
请阅读回答并编辑您的回答,包含解释为何这段代码实际上能够解决手头的问题。请牢记,您不仅要解决问题,还要教育提问者和未来的读者。 - Adriaan
1
这个回答没有帮助,也没有提供按攻击排序的期望行为。证明链接:https://phpize.online/s/pt - mickmackusa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接