PHP数组按配置自动映射

需求是一个源数据按配置映射成目标数组,简单满足

<?php
function array_loop_value(array $arr, string $key, $merge = false) {
    if (isset($arr[$key])) {
        return $arr[$key];
    }

    $keys = explode('.', $key);
    $readKeys = [];
    foreach ($keys as $item) {
        $readKeys[] = $item;
        if (stripos($item, '[]') === strlen($item) - 2) {  // []在结尾, 需要做数组映射
            $tempKey = rtrim($item, '[]');
            $temp = $arr[$tempKey] ?? [];
            $results = [];
            foreach ($temp as $tempItem) {
                $nextKeys = ltrim($key, implode('.', $readKeys).'.');
                $result = array_loop_value($tempItem, $nextKeys, true);
                if ($merge) {
                    $results = array_merge($results, $result);
                } else {
                    $results[] = $result;
                }
            }

            $arr = $results;
            break;
        }

        $arr = $arr[$item] ?? null;
    }

    return $arr;
}

if (!function_exists('array_loop_assignment')) {

    function array_loop_assignment(&$arr, string $key, &$value, bool $shift = false)
    {
        if (empty($key)) {
            return;
        }

        $keys = explode('.', $key);
        $readKeys = [];
        $currents = $arr;
        foreach ($keys as $item) {
            $readKeys[] = $item;
            $nextKeys = ltrim($key, implode('.', $readKeys).'.');
            $currentKey = rtrim($item, '[]');
            $currents = $currents[$currentKey] ?? [];

            if (stripos($item, '[]') === strlen($item) - 2) {

                $currents = array_pad($currents, count($value), []);
                foreach ($currents as &$currentItem) {
                    array_loop_assignment($currentItem, $nextKeys, $value, true);
                }

                $arr[$currentKey] = $currents;

                break;
            }

            if (!empty($nextKeys)) {
                array_loop_assignment($currents, $nextKeys, $value, $shift);
                $arr[$currentKey] = $currents;
                break;
            }

            $arr[$currentKey] = $shift ? array_shift($value) : $value;
        }
    }
}

$source = [
    'aa' => [
        [
            'bb' => 1,
            'cc'  => [
                'dd' => 2
            ],
            'ee' => [
                [
                    'ff' => 5
                ],
                [
                    'ff' => 6
                ]
            ]
        ],
        [
            'bb' => 3,
            'cc'  => [
                'dd' => 4
            ],
            'ee' => [
                [
                    'ff' => 7
                ],
                [
                    'ff' => 8
                ]
            ]
        ],
    ],
    'gg' => 9,
    'hh' => [
        'ii' => 10
    ]
];

echo '<pre>';
$target = [];
$v1 = array_loop_value($source, 'aa');
print_r("1-----------------------------------------------------------------------<br>");
print_r( $v1);
array_loop_assignment($target, 't1', $v1);
print_r($target);

$target = [];
$v2 = array_loop_value($source, 'aa[].bb');
print_r("<br/><br/>2-----------------------------------------------------------------------<br>");
print_r( $v2);
array_loop_assignment($target, 't2[].bb', $v2);
print_r($target);

$target = [];
$v3 = array_loop_value($source, 'aa[].bb');
print_r("<br/><br/>3-----------------------------------------------------------------------<br>");
print_r( $v3);
array_loop_assignment($target, 't3', $v3);
print_r($target);

$target = [];
$v4 = array_loop_value($source, 'aa[].cc');
print_r("<br/><br/>4-----------------------------------------------------------------------<br>");
print_r( $v4);
array_loop_assignment($target, 't4.a41', $v4);
print_r($target);

$target = [];
$v5 = array_loop_value($source, 'gg');
print_r("<br/><br/>5-----------------------------------------------------------------------<br>");
print_r( $v5);
array_loop_assignment($target, 't5.xx.cc', $v5);
print_r($target);

$target = [];
$v6 = array_loop_value($source, 'hh.ii');
print_r("<br/><br/>6-----------------------------------------------------------------------<br>");
print_r( $v6);
array_loop_assignment($target, 't6', $v6);
print_r($target);

echo '</pre>';

发表回复

您的电子邮箱地址不会被公开。