2

I've searched for this on and off for a couple of years to no avail. Occasionally I'd like to prune a multi-dimension to a certain depth. This would be useful when storing large recursive data sets when you only need data to a certain depth and the rest should be discarded.

For example, given the following array:

  $arr = array(
    '1' => array(
      '1.1' => '1.1.1'),
    '2', 
    '3' => array(
      '3.1' => array(
        '3.1.1' => '3.1.1.1')
       )
     );

I would want to prune it back to x number of dimensions calling something like this:

some_prune_method($arr array, $dimensions integer)

...and expect data to be returned something like this:

print_r(some_prune_method($arr, 1));

  Array( 
    [
      '1',
      '2', 
      '3'
    ]
  )

print_r(some_prune_method($arr, 2));

  Array( 
    [
      '1' => ['1.1'], 
      '2', 
      '3' => ['3.1']
    ]
  )

print_r(some_prune_method($arr, 3));

  Array( 
    [
      '1' => ['1.1'], 
      '2', 
      '3' => ['3.1' => '3.1.1']
    ]
  )

I can think how to do this manually using a callback to iterate through the array but that's slow. Ideally this would need to be done WITHOUT iterating through the entire array.

Maybe I'm missing a simple way to do this?

4
  • Can you show us the approach you've taken and resulted to be slow? Commented Aug 8, 2019 at 5:42
  • Why not recursive? also too slow? Commented Aug 8, 2019 at 5:44
  • @dWinder recursive is always slow. There is no recursive algorithm that cant be speeden up by rewriting it without recursion. Commented Aug 8, 2019 at 5:45
  • Anyway if your input didnt contained mixed keys and values i.e. here ['1' => [...], '2'] with depth 1 you want the key of the first item and value of the second. If your inputs looked rather like this: ['1' => [...], '2' => []] Then it would be matter of finding out at which level to call array_keys. But since you mix it, you have to keep checking what you have. Anyway if you want to reduce the entire array, you have to traverse the entire array, one way or the other. Commented Aug 8, 2019 at 5:54

1 Answer 1

1

Think this is what your after. The main concept is just a recursive method to copy the input array which keeps track of the depth. Each time it goes back round it takes 1 off the depth and just before checking if it needs to call the recursive loop it checks if the depth will allow it. If not then it just adds the key to the output loop instead.

$arr = array(
    '1' => array(
        '1.1' => '1.1.1'),
    '2',
    '3' => array(
        '3.1' => array(
            '3.1.1' => '3.1.1.1')
    )
);

function some_prune_method ( $array, $depth )   {
    $output = [];
    foreach ( $array as $key => $element )  {
        if ( is_array($element))  {
            if ( $depth > 1 )   {
                $output [$key] = some_prune_method ( $element, $depth-1 );
            }
            else    {
                $output[] = $key;
            }
        }
        else    {
            $output[] = $element;
        }
    }

    return $output;
}
print_r(some_prune_method($arr, 2));

gives...

Array
(
    [1] => Array
        (
            [0] => 1.1.1
        )

    [2] => 2
    [3] => Array
        (
            [0] => 3.1
        )

)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.