Search code examples
phpmultidimensional-arraynested

Getting subarray data from a deeply nested array in PHP


I would like to extract the data from deeply nested arrays. I am after a function that will yield some part of the array matching some criteria. I am after the data that is found under the 'i' => 'p' subarray Given the nested array below:

              [
                'a' => [
                 'i' => [
                  'p' => [
                    'v' => [
                      'age'  => 10,
                      'name' => 'John',
                      'city' => 'Seattle'
                    ],
                    'l' => [
                      'referee' => 'Jane Smith'
                    ],
                    'm' => [
                      'referee' => 'Jane Smith'
                    ],
                  ]
                ]
              ],
              'b' => [
                'i' => [
                  'p' => [
                    'sibling' => 'Peter'
                  ]
                ],
              ],
              'c' => [
                'i' => [
                  'p' => [
                    'material' => [
                      'i' => [
                        'p' => [
                          'marketId' => [
                            'title' => 'marketplaceId'
                          ],
                          'color' => [
                            'i' => [
                              'p' => [
                                'value' => [
                                  'title' => 'Mr',
                                  "type" => "string"
                                ],
                                'language' => 'C++'
                              ]
                            ]
                          ],
                        ],
                      ]
                    ]
                  ]
                ],
              ],
              'd' => [
                'i' => [
                  'p' => [
                    'schedule' => [
                      'i' => [
                        'p' => [
                          'value' => [
                            'title' => 'your value',
                            'description' => 'your description'
                          ]
                        ]
                      ]
                    ]
                  ]
                ]
              ],
              'e' => [
                'i' => [
                  'p' => [
                    'value' => [
                      'title' => 'your value',
                      'description' => 'your description'
                    ],
                    'language' => [],
                    'marketplace' => []
                  ]
                ],
              ]
            ]

I am looking for something like:

[
 'a' => [
   'v' => [
     'age'  => 10,
     'name' => 'John',
     'city' => 'Seattle'
   ],
   'l' => [
     'referee' => 'Jane Smith'
   ],
   'm' => [
     'referee' => 'Jane Smith'
   ],
 ],
 'b' => [
   'sibling' => 'Peter'
 ],
 'c' => [
   'material' => [
     'marketId' => [
       'title'  => 'marketplaceId'
     ],
     'color' => [
         'value' => [
         'title' => 'Mr',
         "type"  => "string"
       ],
       'language' => 'C++'
     ],
   ]
 ],
 'd' => [
   'schedule' => [
     [
      'value' => [
        'title'       => 'your value',
        'description' => 'your description'
       ]
     ]
   ]
 ],
 'e' => [
   [
     'value' => [
       'title'       => 'your value',
       'description' => 'your description'
     ],
     'language'    => [],
     'marketplace' => []
   ]
 ]
]

I tried this function:

function getIPData($array, $prefix = '') {
  $return = [];
  foreach ($array as $key => $value) {
    if (!empty($value['i']['p'])) {
      $return = array_merge($return, getIPData($value['i']['p'], $prefix . $key . '_'));
    } else {
      echo "Prefix: $prefix Key: $key \n";
      $return[$prefix . $key] = $value;
    }
  }
  return $return;
}

but it is yielding the following array:

Array
(
    [a_v] => Array
        (
            [age] => 10
            [name] => John
            [city] => Seattle
        )

    [a_l] => Array
        (
            [referee] => Jane Smith
        )

    [a_m] => Array
        (
            [referee] => Jane Smith
        )

    [b_sibling] => Peter
    [c_material_marketId] => Array
        (
            [title] => marketplaceId
        )

    [c_material_color_value] => Array
        (
            [title] => Mr
            [type] => string
        )

    [c_material_color_language] => C++
    [d_schedule_value] => Array
        (
            [title] => your value
            [description] => your description
        )

    [e_value] => Array
        (
            [title] => your value
            [description] => your description
        )

    [e_language] => Array
        (
        )

    [e_marketplace] => Array
        (
        )

)


Solution

  • Your code is very close to achieve the goal. Here is my approach.

    1. Remove the [i][p] node if found.
    2. Check for Nested [i][p] by Recursion.

    Additionally, if you need depth control you may add depth and maxDepth to control the nested recursion behavior.

    Function:

    function getIPData($array) {
        $return = [];
        foreach ($array as $key => $value) {
    
            if (!empty($value['i']['p'])) {
                $value = $value['i']['p'];
            }
    
            if (is_array($value)) {
                $value = getIPData($value);
            }
    
            $return[$key] = $value;
        }
        return $return;
    }
    

    Output:

    Array
    (
        [a] => Array
            (
                [v] => Array
                    (
                        [age] => 10
                        [name] => John
                        [city] => Seattle
                    )
    
                [l] => Array
                    (
                        [referee] => Jane Smith
                    )
    
                [m] => Array
                    (
                        [referee] => Jane Smith
                    )
    
            )
    
        [b] => Array
            (
                [sibling] => Peter
            )
    
        [c] => Array
            (
                [material] => Array
                    (
                        [marketId] => Array
                            (
                                [title] => marketplaceId
                            )
    
                        [color] => Array
                            (
                                [value] => Array
                                    (
                                        [title] => Mr
                                        [type] => string
                                    )
    
                                [language] => C++
                            )
    
                    )
    
            )
    
        [d] => Array
            (
                [schedule] => Array
                    (
                        [value] => Array
                            (
                                [title] => your value
                                [description] => your description
                            )
    
                    )
    
            )
    
        [e] => Array
            (
                [value] => Array
                    (
                        [title] => your value
                        [description] => your description
                    )
    
                [language] => Array
                    (
                    )
    
                [marketplace] => Array
                    (
                    )
    
            )
    
    )
    

    Please feel free to communicate if requires