Fabio.
Fabio.

Reputation: 9

Flatten multidimensional arrays

I can't find a good answer to recoursively remove empty arrays from a multidimensional array.

I have for example this array:

$array = [
    [
        [
            [
                'some key' => 'some value'
            ]
        ]
    ]
];

after I want to have something like this:

$array = [
    'some key' => 'some value'
];

I cant find a solution to do this. My solution to this works only without a key value pair.

$array = array_map('array_filter', $array);
$array = array_filter($array);

Upvotes: -1

Views: 106

Answers (4)

Progrock
Progrock

Reputation: 7485

You can access array 'leaves' easily with array_walk_recursive:

<?php
$array = [
    [
        [
            [
                'some key' => 'some value'
            ]
        ]
    ]
];

array_walk_recursive($array, function($v, $k) use (&$result) {
    $result[$k] = $v;
});

var_export($result);

Output:

array (
  'some key' => 'some value',
)

Upvotes: 0

Martin
Martin

Reputation: 16423

You could achieve this by walking down the arrays recursively until the array_key is not 0:

while (is_array($array) && count($array) == 1 && array_keys($array)[0] === 0)
    $array = $array[0];

Output:

var_dump($array);

array(1) {
  ["some key"]=>
  string(10) "some value"
}

How does this work?

Whilst:

  • The $array is an array
  • The number of items in the array is 1
  • The first array key is 0

The while loop will set $array to be the item with key 0.

This will not be true for the array you are looking for.

Upvotes: 1

Nicolas
Nicolas

Reputation: 8650

You had the right idea with recursivity. What you could do is check if the current element is an array, and if it is, you call the function with that array again until you find an element that is not an array. You could return this element in another array that would recursively get filled with non empty values.

i've created this simple function that work for your example. It won't work if you have multiple element like this one in your arrays.

<?php
// example code

$array = [
    [
        [
            [
                'some key' => 'some value'
            ]
        ]
    ]
];

function recursivelyRemoveTechnicallyNotEmptyArray($array) {
    // this will keep the value that are not emtpy
    $arrayWithValue = [];
    // in our case. the first case can be 0 or "some key". We need to take care of both cases.
    $firstkey = array_keys($array)[0];
    // if the first element is an array, we do a recursive call with that element
    if(is_array($array[$firstkey])) {
        // we append the result of the recursive call to the current return value.
        $arrayWithValue = array_merge($arrayWithValue, recursivelyRemoveTechnicallyNotEmptyArray($array[$firstkey]));
    } else {
        // it is not an array, we push it into what we are going to return
        $arrayWithValue[] = $array[$firstkey];
    }
    return $arrayWithValue;
}

var_dump(recursivelyRemoveTechnicallyNotEmptyArray($array));

I've also created a playground for you to test.

Upvotes: 0

Tyralcori
Tyralcori

Reputation: 1047

As @vivek_23 said, technically it is not empty, but that would be one way to go:

<?php

$array = [
    [
        [
            [
                'some key' => 'some value',
            ]
        ]
    ]
];

function recursiveSanitizer($input) {
    foreach ($input as $layer) {
        if (isset($layer[0]) && !empty($layer[0])) {
            return recursiveSanitizer($layer);
        } else {
            return $layer;
        }
    }
}

var_dump(recursiveSanitizer($array));

Upvotes: 1

Related Questions