首页 > 解决方案 > PHP嵌套数组:内爆每个叶子的所有树键会产生一个多维数组而不是一维关联数组

问题描述

从嵌套数组中,我想生成一维关联数组,其中包含每个叶子的升序键连接。

概括

  1. 预期结果示例

    1.1。输入

    1.2. 输出

  2. 实际结果示例

    1.1。输入

    1.2. 输出

  3. 问题

  4. 最小的、可测试的可执行源

    4.1。解释

    4.2. 来源与执行


预期结果示例

输入

以下嵌套数组:

[
   'key1' => 'foo',
   'key2' => [
         'key3' => [
               0 => ['key4' => 'bar' ],
               1 => ['key4' => 'azerty']
         ]
   ]    
]

输出

以下一维关联数组(键连接的粘合字符:)_

[
   'key1' => 'foo', 
   'key2_key3_0_key4' => 'bar',
   'key2_key3_1_key4' => 'azerty'
]

实际结果示例

输入

[
   'etat' => 'bar',
   'proposition_en_cours' => [
         'fichiers' => [
               0 => ['url_fichier' => 'foo' ],
               1 => ['url_fichier' => 'bar']
         ]
   ]    
]

输出

Array
(
    [] => bar
    [proposition_en_cours] => Array
        (
            [fichiers] => Array
                (
                    [0] => Array
                        (
                            [url_fichier] => foo
                        )

                    [1] => Array
                        (
                            [url_fichier] => bar
                        )

                )

        )

    [proposition_en_cours_fichiers] => Array
        (
            [0] => Array
                (
                    [url_fichier] => foo
                )

            [1] => Array
                (
                    [url_fichier] => bar
                )

        )

    [proposition_en_cours_fichiers_0] => foo
    [proposition_en_cours_fichiers_0_1] => bar
)

问题

如您所见,我得到的数组在所有点上都与预期的不同。我不知道为什么。

最小的、可测试的可执行源

解释

我初始化了一个数组,该数组必须包含每个叶子的所有升序键:$key_in_db_format = [];

我迭代输入数组。$key_in_db_format对于每个元素(叶子或子数组),当且仅当当前深度等于最后一个深度时,我才会弹出。如果它是一个数组(即:不是叶子):我将键添加到$key_in_db_format. 我在键上设置了一个值(叶子),它是升序键的串联。

来源与执行

  1. 首先,在您选择的空 PHP 脚本中定义此数组:

    $values = [
    
        'etat' => 'bar',
    
        'proposition_en_cours' => [
            'fichiers' => [
                0 => [ 'url_fichier' => 'foo' ],
                1 => [ 'url_fichier' => 'bar' ]
             ]
        ]
    
    ];
    
  2. 然后,复制/粘贴以下代码,您将能够执行它:

     $values_to_insert_in_meta_table = [];
    
     $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($values), \RecursiveIteratorIterator::SELF_FIRST);
     $last_depth = 0;
     $key_in_db_format = [];
     foreach ($iterator as $value_key_field => $value_value_field) {
         if($iterator->getDepth() == $last_depth) {
             array_pop($key_in_db_format);
         }
    
         if(is_array($value_value_field)) {
             array_push($key_in_db_format, $value_key_field);
         } else {
             $values_to_insert_in_meta_table[implode('_', $key_in_db_format)] = $value_value_field;
         }
    
    
         $last_depth = $iterator->getDepth();
     }
    
     echo '<pre>';
     print_r($values_to_insert_in_meta_table);
    

标签: phparraysrecursion

解决方案


也许我错过了一些东西,但据我所知,我会做这样的事情:

<?php

function flatten(array $array, ?string $prefix = null): array {
    $prefix = $prefix === null ? '' : "{$prefix}_";
    $output = [];

    foreach ($array as $key => $value) {
        $key = $prefix . $key;

        if (is_array($value)) {
            $output = array_merge($output, flatten($value, $key));
        } else {
            $output[$key] = $value;
        }
    }

    return $output;
}

var_export(flatten([
    'key1' => 'foo',
    'key2' => [
        'key3' => [
            0 => ['key4' => 'bar' ],
            1 => ['key4' => 'azerty']
        ]
    ]
]));

输出:

array (
  'key1' => 'foo',
  'key2_key3_0_key4' => 'bar',
  'key2_key3_1_key4' => 'azerty',
)

推荐阅读