Php 将数组动态转换为键值对数组

Php 将数组动态转换为键值对数组,php,recursion,Php,Recursion,这是我拥有的阵列的一个示例: $data = [ 'total_amount' => 200, 'purchase_date' => '01.01.2020', 'items' => [ [ 'name' => 'T-shirt', 'price' => 50 ], [

这是我拥有的阵列的一个示例:

 $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
                ]
           ]
        ]
    ]
]
解析第一个数组,然后创建所需的输出,这不是什么大问题。另外,如果我们有嵌套的、nasted的和嵌套的数组,那么我只使用递归,它似乎工作得很好。 以下是我的代码:

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函数,我可以利用),并避免递归?

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

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

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

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

要收紧/D.R.Y.-out您的代码,请识别多次编写的进程,并尝试以允许单个函数调用或进程声明的方式重构脚本

  • 您知道,当
    $value
    是一个数组时,需要使用递归,因此有条件地将递归的返回值调用并缓存到变量中
  • 您知道,当键不是索引时,需要将新的关联结构推送到输出数组中,因此有条件地推送所需的内容
  • 使用以下方法,您可以在不需要冗余脚本的情况下获得所需的输出

    代码:()


    要收紧/D.R.Y.-out您的代码,请识别多次编写的进程,并尝试以允许单个函数调用或进程声明的方式重构脚本

  • 您知道,当
    $value
    是一个数组时,需要使用递归,因此有条件地将递归的返回值调用并缓存到变量中
  • 您知道,当键不是索引时,需要将新的关联结构推送到输出数组中,因此有条件地推送所需的内容
  • 使用以下方法,您可以在不需要冗余脚本的情况下获得所需的输出

    代码:()


    谢谢你的支持。这是实现预期目标的最佳方式。感谢您的支持。这是实现预期目标的最好、最干净的方法。