【问题标题】:Trying to sort an associative array in PHP尝试在 PHP 中对关联数组进行排序
【发布时间】:2019-04-01 01:40:35
【问题描述】:

我正在尝试在 PHP 中对这个关联数组进行排序,按字段 name 排序

$fonts = array(
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
);

我要做的是按名称对条目进行排序,但保留与条目本身关联的键,所以我想要的是:

 $fonts = array(
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
);

这是暴露问题的最少代码(PHP 版本 +7):

function cmp($a, $b)
{
    return strcmp($a["name"], $b["name"]);
}

$fonts = array(
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
);

uasort($fonts, "cmp");

for($i = 0; $i < 4; $i++)
{
    echo "<br/>".$fonts[$i]["name"];
}

我正在使用uasort(),因为它应该在对数组进行排序时保持键的关联。不幸的是,如果我打印数组,我会得到相同的顺序,即:

Arial
Times
Roboto
AlexBrush

【问题讨论】:

    标签: php arrays sorting associative-array


    【解决方案1】:

    像这样按 name 执行sort 并使用foreach() 循环

    <?php
    
    $fonts = array(
        0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
        1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
        2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
        3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
    );
    
    uasort($fonts, function($a, $b) {
        return strcmp($a['name'], $b['name']);
    });
    
    print_r($fonts);
    
    foreach($fonts as $font){
     echo $font["name"].PHP_EOL;
    }
    
    ?>
    

    编辑:根据 OP 的评论,

     $indexed_array = array_column($fonts,'name','index'); // array column map name by index
     print_r($indexed_array); 
     echo $indexed_array[3];
    

    演示: https://3v4l.org/W7BOH

    【讨论】:

    • 如果我有索引 3 如何从排序数组中检索 AlexBrush?你能告诉我怎么做吗
    • @GianlucaGhettini 我已根据您的评论编辑我的答案。再看看:)
    • 我得到了一些奇怪的东西,比如“A”、“T”、“R”、“A”
    • 你把它放在循环里面了吗?
    • 好的,现在很好......我不明白数组是否正确排序,这是我循环遍历它的方式是错误的。 Foreach 解决了这个问题
    【解决方案2】:

    当你正在使用...

    for($i = 0; $i < 4; $i++)
    {
        echo "<br/>".$fonts[$i]["name"];
    }
    

    要打印出这些值,您需要按数字顺序使用索引来显示它们。

    如果你使用...

    print_r($fonts);
    

    您会看到它们已被排序并得到...

    Array
    (
        [3] => Array
            (
                [index] => 3
                [name] => AlexBrush
                [path] => assets/fonts/AlexBrush-Regular.ttf
            )
    
        [0] => Array
            (
                [index] => 0
                [name] => Arial
                [path] => assets/fonts/arial.ttf
            )
    
        [2] => Array
            (
                [index] => 2
                [name] => Roboto
                [path] => assets/fonts/roboto.ttf
            )
    
        [1] => Array
            (
                [index] => 1
                [name] => Times
                [path] => assets/fonts/times.ttf
            )
    
    )
    

    或者正如 L. Faros 在 cmets 中指出的那样,如果您使用...

    foreach ( $fonts as $font ) {
        echo "<br/>".$font["name"];
    }
    

    你会得到

    <br/>AlexBrush<br/>Arial<br/>Roboto<br/>Times
    

    【讨论】:

    • 我不明白,PHP 不应该威胁我作为关联数组“键”提供的 $i 索引吗?
    • 是的,但是您要求的键是 0,1,2,3 - 这与要求数组的位置 0,1,... 中的元素不同。您希望维护密钥,并且一直如此。
    • 假设我想访问元素键 = 3 (AlexBrush)。我怎样才能在 PHP 中做到这一点? $font[3] 不像你说的那样工作,那么给定 3 怎么办?我想要类似 $alexbrush = $fonts.key(3);
    • 可能值得一提的是,如果你想遍历数组并保持数组按字体名称排序,你应该使用foreach
    • 如果您想访问AlexBrush 元素,请使用echo $fonts[3]["name"];
    【解决方案3】:

    您可以使用array_column 使数组具有关联性,然后使用kso​​rt(键排序)进行排序。

    $fonts = array_column($fonts, null, "name");
    ksort($fonts);
    $fonts = array_values($fonts);
    var_dump($fonts);
    

    输出:

    array(4) {
      [0]=>
      array(3) {
        ["index"]=>
        int(3)
        ["name"]=>
        string(9) "AlexBrush"
        ["path"]=>
        string(34) "assets/fonts/AlexBrush-Regular.ttf"
      }
      [1]=>
      array(3) {
        ["index"]=>
        int(0)
        ["name"]=>
        string(5) "Arial"
        ["path"]=>
        string(22) "assets/fonts/arial.ttf"
      }
      [2]=>
      array(3) {
        ["index"]=>
        int(2)
        ["name"]=>
        string(6) "Roboto"
        ["path"]=>
        string(23) "assets/fonts/roboto.ttf"
      }
      [3]=>
      array(3) {
        ["index"]=>
        int(1)
        ["name"]=>
        string(5) "Times"
        ["path"]=>
        string(22) "assets/fonts/times.ttf"
      }
    }
    

    这意味着您可以像在问题中所做的那样迭代数组。

    https://3v4l.org/pJXfp


    我看到您询问如何获取索引 3 名称。

    在这种情况下,再次使用 array_column 使其与索引关联。

    https://3v4l.org/nCtJf

    $fonts = array_column($fonts, null, "name");
    ksort($fonts);
    $fonts = array_column($fonts, null, "index");
    
    echo $fonts[3]["name"]; //AlexBrush
    

    【讨论】:

      【解决方案4】:

      如果您要继续使用for(),您实际上需要重新索引第一级键——这没什么大不了的,因为您仍然在index 元素中保留了原始数字ID。

      按照这个逻辑,我可以推荐两种不同的单行代码。

      1. array_multisort(array_column($fonts, 'name'), $fonts);
      2. usort($fonts, function($a, $b){return $a['name'] &lt;=&gt; $b['name'];});

      Demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-26
        • 2010-10-21
        • 2014-05-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多