首页 > 解决方案 > 将数组动态转换为键值对数组

问题描述

这是我拥有的数组示例:

 $data = [
      'total_amount' => 200,
      'purchase_date' => '01.01.2020',
      'items' => [
           [
                'name' => 'T-shirt',
                'price' => 50
           ],
           [
                'name' => 'Jacket',
                'price' => 150
           ],
       ]
];

我想得到这样的东西:

$data = [
    [
        'k' => 'total_amount',
        'v' => 200
    ],
    [
        'k' => 'purchase_date',
        'v' => '01.01.2020'
    ]
    [
        'k' => 'items',
        'v' => [
           [
                [
                    'k' => 'name',
                    'v' => 'T-Shirt'
                ],
                [
                    'k' => 'price',
                    'v' => 50
                ]
           ],
           [
                [
                    'k' => 'name',
                    'v' => 'Jacket'
                ],
                [
                    'k' => 'price',
                    'v' => 150
                ]
           ]
        ]
    ]
]

解析第一个数组然后创建所需的输出并不是什么大问题。此外,如果我们有嵌套和嵌套数组,那么我只使用递归,它似乎工作得很好。这是我的代码:

public function convert(array $data) : array
{
    $output = [];

    foreach ($data as $k => $v) {
        if (is_array($v)) {
            $output[] = ['k' => $k, 'v' => $this->value($v)];
        } else {
            $output[] = ['k' => $k, 'v' => $v];
        }
    }

    return $output;
}

以及以下内容:

   protected function value($items)
{
    $output = [];
    $i = 0;

    foreach ($items as $itemK => $itemV) {
        if (!is_array($itemV)) {
            $output[$i] = ['k' => $itemK, 'v' => $itemV];
            continue;
        }

        foreach ($itemV as $k => $v) {
            if (is_array($v)) {
                $output[$i][] = ['k' => $k, 'v' => $this->value($v)];
                continue;
            }

            $output[$i][] = ['k' => $k, 'v' => $v];
        }

        $i++;
    }

    return $output;
}

问题是是否有一种方法可以在不使用太多 foreach 函数的情况下优化此代码(也许有我可以利用的内置 PHP 函数)并且可能避免递归?

标签: phprecursion

解决方案


这是您的代码的稍微简化的版本。请注意,如果您想允许任意嵌套的键/值对,递归是唯一有效的方法:

function convert($array) {
    $output = array();
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            // nested array with numeric keys? if so don't create a k,v pair
            if (is_numeric($key)) {
                $output[] = convert($value);
            }
            else {
                $output[] = array('k' => $key, 'v' => convert($value));
            }
        }
        else {
            $output[] = array('k' => $key, 'v' => $value);
        }
    }
    return $output;
}

输出:

Array
(
    [0] => Array
        (
            [k] => total_amount
            [v] => 200
        )
    [1] => Array
        (
            [k] => purchase_date
            [v] => 01.01.2020
        )
    [2] => Array
        (
            [k] => items
            [v] => Array
                (
                    [0] => Array
                        (
                            [0] => Array
                                (
                                    [k] => name
                                    [v] => T-shirt
                                )
                            [1] => Array
                                (
                                    [k] => price
                                    [v] => 50
                                )
                        )
                    [1] => Array
                        (
                            [0] => Array
                                (
                                    [k] => name
                                    [v] => Jacket
                                )
                            [1] => Array
                                (
                                    [k] => price
                                    [v] => 150
                                )
                        )
                )
        )
)

3v4l.org 上的演示


推荐阅读