Я пытаюсь отсортировать этот ассоциативный массив в 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
Поскольку вы используете ...
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
)
)
Или, как указал Л. Фарос в комментариях, если вы использовали ...
foreach ( $fonts as $font ) {
echo "<br/>".$font["name"];
}
вы бы получили
<br/>AlexBrush<br/>Arial<br/>Roboto<br/>Times
Это так, но ключ, который вы запрашиваете, - 0,1,2,3 - это не то же самое, что запрос элемента в позиции 0,1, ... массива. Вы хотели сохранить ключ, и так оно и было.
Допустим, я хочу получить доступ к элементу key = 3 (AlexBrush). Как это сделать на PHP? $ font [3] не работает, как вы сказали, так как я могу это сделать, учитывая 3? Я бы хотел иметь что-то вроде $ alexbrush = $ fonts.key (3);
Возможно, стоит упомянуть, что если вы хотите перебрать массив и сохранить массив, упорядоченный по имени шрифта, вы должны использовать foreach
Если вы хотите получить доступ к элементу AlexBrush
, используйте echo $fonts[3]["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];
Если у меня есть индекс 3, как я могу получить AlexBrush из отсортированного массива? Не могли бы вы показать мне, как это сделать?
@GianlucaGhettini Я Отредактировано мой ответ, основанный на вашем комментарии. Посмотрите еще раз :)
Я получаю что-то странное, например "А", "Т", "Р", "А"
ты поместил это внутрь цикла?
хорошо, теперь все в порядке ... Я не понял, что массив отсортирован правильно, это то, как я его перебираю, было неправильным. Foreach решил проблему
Хорошо, сэр, удачи :)
Вы можете использовать array_column, чтобы сделать массив ассоциативным, а затем отсортировать с помощью ksort (сортировка по ключу).
$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"
}
}
Это означает, что вы можете перебирать массив, как вы это сделали в своем вопросе.
Я вижу, вы спрашиваете, как получить имя индекса 3.
В этом случае снова используйте array_column, чтобы сделать его ассоциативным по индексу.
$fonts = array_column($fonts, null, "name");
ksort($fonts);
$fonts = array_column($fonts, null, "index");
echo $fonts[3]["name"]; //AlexBrush
Если вы собираетесь продолжать использовать for()
, вам действительно нужно повторно проиндексировать ключи первого уровня - что не представляет большого труда, потому что у вас все еще есть исходные числовые идентификаторы, сохраненные в элементах index
.
Следуя этой логике, я могу порекомендовать два разных однострочных сообщения.
array_multisort(array_column($fonts, 'name'), $fonts);
usort($fonts, function($a, $b){return $a['name'] <=> $b['name'];});
Я не понимаю, не должен ли PHP угрожать индексу $ i, который я предоставляю в качестве «ключа» для моего ассоциативного массива?