PHP将数组格式化为新数组

PHP将数组格式化为新数组,php,arrays,foreach,mapping,Php,Arrays,Foreach,Mapping,大家好,我是PHP的初学者,希望以最佳的性能方式转换此数组: $old = array( 20 => array( 'name' => 'Heels', 'path' => '1/2/10/15/20', ), 15 => array( 'name' => 'Sandals', 'path' => '1

大家好,我是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',
        ),
);

将会有大量的记录爆炸路径,并用ID映射它们,这会降低性能,只是想知道是否有一种更有效的方法,如果可能的话,谢谢

这是硬编码的方式,但我认为您需要提供更多信息以获得动态解决方案

<?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
您可以首先对键(ID)进行排序,然后在创建面包屑的数组中循环

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
这是一本书

输出:

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);

如果
路径(您正在解释的路径)不同,那么值20的来源我就不知道了?请提供一个输入和输出的最小、完整或可验证的示例。20是每个路径的结束号,但也是键,因此最终结果需要为每个路径的键名值1和2添加值,如果这样做有意义,则将其排除。@NewHorizon这没有意义。你能澄清一下你的逻辑吗?你说“20是每个路径的结束数字”,但
'1/2/80/96/15'
中没有20。这些只是虚拟数据的假数字,但所有数据都会与最后三个数字匹配。在提问时发布正确的数据性能方面的好主意,还可以大量使用
数组列()
而不是循环为使用
内爆()的名称创建一个全新的变量。希望你不介意我偷了它来更新我的问题;)回答得好。这个答案是最有活力的解决方案,我不明白为什么它没有更多的选票。我欣赏这样一个概念,即不仅要将OP输入匹配到输出,还要允许放置更多的输入,这些输入仍然可以查询OP输出的意图。老实说,这是一个很好的解决方案,让我开始研究“地图绘制者”。