Попытка отсортировать ассоциативный массив в 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 +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 в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
50
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Поскольку вы используете ...

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

Я не понимаю, не должен ли PHP угрожать индексу $ i, который я предоставляю в качестве «ключа» для моего ассоциативного массива?

Gianluca Ghettini 27.10.2018 17:08

Это так, но ключ, который вы запрашиваете, - 0,1,2,3 - это не то же самое, что запрос элемента в позиции 0,1, ... массива. Вы хотели сохранить ключ, и так оно и было.

Nigel Ren 27.10.2018 17:10

Допустим, я хочу получить доступ к элементу key = 3 (AlexBrush). Как это сделать на PHP? $ font [3] не работает, как вы сказали, так как я могу это сделать, учитывая 3? Я бы хотел иметь что-то вроде $ alexbrush = $ fonts.key (3);

Gianluca Ghettini 27.10.2018 17:11

Возможно, стоит упомянуть, что если вы хотите перебрать массив и сохранить массив, упорядоченный по имени шрифта, вы должны использовать foreach

L. Faros 27.10.2018 17:12

Если вы хотите получить доступ к элементу AlexBrush, используйте echo $fonts[3]["name"];

Nigel Ren 27.10.2018 17:18
Ответ принят как подходящий

Сделайте 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 из отсортированного массива? Не могли бы вы показать мне, как это сделать?

Gianluca Ghettini 27.10.2018 17:15

@GianlucaGhettini Я Отредактировано мой ответ, основанный на вашем комментарии. Посмотрите еще раз :)

Always Sunny 27.10.2018 17:19

Я получаю что-то странное, например "А", "Т", "Р", "А"

Gianluca Ghettini 27.10.2018 17:22

ты поместил это внутрь цикла?

Always Sunny 27.10.2018 17:23

хорошо, теперь все в порядке ... Я не понял, что массив отсортирован правильно, это то, как я его перебираю, было неправильным. Foreach решил проблему

Gianluca Ghettini 27.10.2018 17:25

Хорошо, сэр, удачи :)

Always Sunny 27.10.2018 17:26

Вы можете использовать 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"
  }
}

Это означает, что вы можете перебирать массив, как вы это сделали в своем вопросе.

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(), вам действительно нужно повторно проиндексировать ключи первого уровня - что не представляет большого труда, потому что у вас все еще есть исходные числовые идентификаторы, сохраненные в элементах index.

Следуя этой логике, я могу порекомендовать два разных однострочных сообщения.

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

Демо

Другие вопросы по теме