Привет, ребята, я новичок в 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 - это конечный номер для каждого пути, но это также и ключ, поэтому в конечном результате необходимо, чтобы каждое из значений имени ключа 1 и 2 из каждого пути было исключено, если это имеет смысл.
@NewHorizon В этом нет смысла. Вы можете пояснить здесь свою логику? Вы говорите: «20 - это конечное число для каждого пути», но в '1/2/80/96/15'
нигде нет 20.
Это просто поддельные числа для фиктивных данных, но все три последних числа будут совпадать.
Публикуйте правильные данные, когда задаете вопрос
Это жестко запрограммированный способ, но я думаю, вам нужно предоставить немного больше информации, чтобы получить динамическое решение.
<?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);
Хорошая идея для производительности, а также отличное использование array_column()
вместо циклического создания совершенно новой переменной для имен для использования implode()
. Надеюсь, вы не возражали, что я украл это, чтобы обновить свой вопрос;) Хороший ответ.
Этот ответ - наиболее динамичное решение, я не понимаю, почему у него нет большего количества голосов. Я восхищаюсь концепцией не только сопоставления входа OP с выходом, но и возможности размещения большего количества входов, которые по-прежнему запрашивают, как предназначен выход OP. Честно говоря, отличное решение заставило меня заглянуть в «мапперов».
Я не понимаю, откуда берется значение 20, если
path
(из которого вы объясняете, создает родственников) разные? Пожалуйста, предоставьте минимальный, полный или поддающийся проверке пример ввода и вывода.