尝试对 PHP 中的关联数组进行排序

Trying to sort an associative array in PHP

我试图在 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 ver +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

当您使用...

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 在评论中指出的那样,如果您使用...

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

你会得到

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

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

您可以使用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

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

根据这一逻辑,我可以推荐两种不同的单行代码。

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

Demo