7
\$\begingroup\$

This is a wonky PHP function I came up with to merge some select values from child arrays into the original. It could really use some help simplifying / making it more elegant.

Is there a built-in method I'm overlooking? array_push didn't work for me because the data needed to be flat.

The problem

What I've got:

array(
    array(
         'nice_value' => 'yup',
         'nice_value2' => 'yup again',
         'ono' => array(
              'nice_value3' => 'yup yup yup',
              'bad value' => 'nope'
          )

    ),
    // array with the same format
    [...]

);

What I need:

array(
    array(
         'nice_value' => 'yup',
         'nice_value2' => 'yup again',
         'nice_value3' => 'yup yup yup'
    ),
    // array with the same format
    [...]

);

The wonky solution

// calling in multidimensional array from an api
            $lists = $all_lists['data'];
// keys to merge into the parent array, 'key_to_be' => 'key_that_is'
            $keys_to_merge = array('members' => 'member_count');
// init the function
            $newList = merge_selected_values($lists, $keys_to_merge);


// start writing our function
            function merge_selected_values($list, $keys_to_merge) {
// initialize our return array
            $newList = array();
// start a counter
            $ii = 0;
// begin loop
            foreach($list as $key => $value) {
// get first series of array, this is what we want to merge into
                if (is_array($value)) {
// loop through these values
                   foreach ($value as $kk => $vv) {
// find all arrays that are children of our parent array
                      if (is_array($vv)) {
// loop through these child arrays
                          foreach ($vv as $stats_key => $stats_value) {
// start looping through the keys that we want to merge
                             foreach ($keys_to_merge as $keys => $vals) {
// if the key matches 
                                 if ($stats_key === $vals) {
// create a variable to hold it
                                     ${$vals} = $stats_value;
                                 }
                             }
                         }
                      }
                   }
// start looping through keys to merge again
                   foreach ($keys_to_merge as $keys => $vals) {
// find the keys we merged
                       if (${$vals}) {
// create an array that is the merger, merge to existing array if it .. exists
                           if($newList[$ii]) {
                               $newList[$ii] = array_merge($newList[$ii], array($keys => ${$vals}));
                            }  else {
                              $newList[$ii] = array_merge($value, array($keys => ${$vals})); 
                           }
                       }
                   }
               }
              $ii++;
            }
            return $newList;
            }
\$\endgroup\$
1

2 Answers 2

4
\$\begingroup\$

What's the criteria for deciding which keys to keep?

Check out the array_walk_recursive() function. For example, the following matches any element with a key that starts with "nice_value".

$array = /*your array example*/;
$filtered = array();
array_walk_recursive($array, function($val, $key) use(&$filtered) {
    if (strpos($key, 'nice_value') === 0) {
        $filtered[$key] = $val;
    }
});
\$\endgroup\$
1
\$\begingroup\$

What's wonky

  • The function line is at the same indentation level as its body.
  • The placement and verbosity of the comments.
  • Use of variably-named variables. Gather the key-value pairs to be merged using an associative array instead.

Suggested solution

  • Use array_walk_recursive() as suggested by @jbarreiros to find the key-value pairs you want.
  • Use array_replace() (or maybe array_merge()) to add those key-value pairs back to the original.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.