Форматирование массива PHP в новый массив

Привет, ребята, я новичок в PHP и хочу наилучшим образом с точки зрения производительности преобразовать этот массив:

$old = array(
    20 =>
        array(
            'name' => 'Heels',
            'path' => '1/2/10/15/20',
        ),
    15 =>
        array(
            'name' => 'Sandals',
            'path' => '1/2/80/96/15',
        ),
    10 =>
        array(
            'name' => 'Trainers',
            'path' => '1/2/80/96/10',
        ),
);

К этому:

$new = array(
    20 =>
        array(
            'value' => 20,
            'label' => 'Trainers > Sandals > Heels',
        ),
);

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

Я не понимаю, откуда берется значение 20, если path (из которого вы объясняете, создает родственников) разные? Пожалуйста, предоставьте минимальный, полный или поддающийся проверке пример ввода и вывода.

Jaquarh 18.12.2018 18:27

20 - это конечный номер для каждого пути, но это также и ключ, поэтому в конечном результате необходимо, чтобы каждое из значений имени ключа 1 и 2 из каждого пути было исключено, если это имеет смысл.

New Horizon 18.12.2018 18:31

@NewHorizon В этом нет смысла. Вы можете пояснить здесь свою логику? Вы говорите: «20 - это конечное число для каждого пути», но в '1/2/80/96/15' нигде нет 20.

ggorlen 18.12.2018 18:39

Это просто поддельные числа для фиктивных данных, но все три последних числа будут совпадать.

New Horizon 18.12.2018 18:45

Публикуйте правильные данные, когда задаете вопрос

Andreas 18.12.2018 19:00
Стоит ли изучать 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 и хотите разрабатывать...
1
5
73
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это жестко запрограммированный способ, но я думаю, вам нужно предоставить немного больше информации, чтобы получить динамическое решение.

<?php

$old = array(
    20 =>
        array(
            'name' => 'Heels',
            'path' => '1/2/10/15/20',
        ),
    15 =>
        array(
            'name' => 'Sandals',
            'path' => '1/2/80/96/15',
        ),
    10 =>
        array(
            'name' => 'Trainers',
            'path' => '1/2/80/96/10',
        ),
);


ksort($old);
$breadcrumbs = [];
$currentKey = 0;

foreach ( $old as $itemKey => $item) {
    $currentKey = $itemKey;
    $breadcrumbs[] = $item;

}
$new = [$currentKey] = [
    'value' => $currentKey,
    'label' => implode(' > ', $breadcrumbs)
];

printf($new);

Если я правильно понимаю, вы пытаетесь получить последний путь, относящийся к каждой категории, и вывести его в виде цепочки навигации.

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

arsort($paths); # This gives the desired output in OP but makes more sense to use krsort() to sort DESC not ASC

$breadcrumb = (object) array (
    'value' => array_keys($paths)[count($paths) - 1], # Get the highest id - if using krsort() use array_keys($paths)[0]
    'labels' => implode(' > ', array_column($paths, 'name'));
);

# Update derived from The fourth bird's answer which skips the need for the foreach().
# Concept is to build an array of the labels to then make look pretty with the > effect

Вот демонстрация.

Output:

object (stdClass) (2) {
    ["value"] => int(20)
    ["labels"] => string(26) "Trainers > Sandals > Heels"
}
Ответ принят как подходящий

Другой вариант - сначала создать сопоставитель ключей и имен. Затем вы можете взять ключ у картографа, чтобы создать путь:

$result = [];
$mapper = array_combine(array_keys($old), array_column($old, 'name'));
foreach ($old as $key => $value) {
    $path = implode(' > ', array_map(function($x) use ($mapper) {
        return $mapper[(int)$x];
    }, explode('/', $value['path'])));

    $result[$key] = ['value' => $key,'label' => $path];
}

print_r($result);

Демо PHP

Хорошая идея для производительности, а также отличное использование array_column() вместо циклического создания совершенно новой переменной для имен для использования implode(). Надеюсь, вы не возражали, что я украл это, чтобы обновить свой вопрос;) Хороший ответ.

Jaquarh 18.12.2018 19:01

Этот ответ - наиболее динамичное решение, я не понимаю, почему у него нет большего количества голосов. Я восхищаюсь концепцией не только сопоставления входа OP с выходом, но и возможности размещения большего количества входов, которые по-прежнему запрашивают, как предназначен выход OP. Честно говоря, отличное решение заставило меня заглянуть в «мапперов».

Jaquarh 31.12.2018 17:35

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