Skip to content

Instantly share code, notes, and snippets.

@SeanCannon
Last active October 28, 2024 18:01
Show Gist options
  • Save SeanCannon/6585889 to your computer and use it in GitHub Desktop.
Save SeanCannon/6585889 to your computer and use it in GitHub Desktop.
PHP array_flatten() function. Convert a multi-dimensional array into a single-dimensional array.
<?php
/**
* Convert a multi-dimensional array into a single-dimensional array.
* @author Sean Cannon, LitmusBox.com | seanc@litmusbox.com
* @param array $array The multi-dimensional array.
* @return array
*/
function array_flatten($array) {
if (!is_array($array)) {
return false;
}
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$result = array_merge($result, array_flatten($value));
} else {
$result = array_merge($result, array($key => $value));
}
}
return $result;
}
@sayhicoelho
Copy link

sayhicoelho commented Feb 15, 2024

Nice @graceman9, but it doesn't work in PHP 7, as unpacking arrays with string keys was only implemented in PHP 8.

Fatal error: Uncaught Error: Cannot unpack array with string keys

Ref: https://wiki.php.net/rfc/array_unpacking_string_keys

I just changed ... with array_merge to make your code compatible with older versions of PHP.

function true_flatten(array $array, array $parents = [])
{
    $return = [];
    foreach ($array as $k => $value) {
        $p = empty($parents) ? [$k] : array_merge($parents, [$k]);
        if (is_array($value)) {
            $return = array_merge($return, true_flatten($value, $p));
        } else {
            $return[implode('_', $p)] = $value;
        }
    }

    return $return;
}

Output:

Array
(
    [a] => value1
    [b_c] => value1.1
    [b_d] => value1.2
    [e] => value2
    [f_j_k] => value2.1
    [f_j_m] => value2.2
    [f_j_n] => value2.3
    [o] => value3
    [p_some_very_deep_item_0] => first
    [p_some_very_deep_item_1] => second
    [q] => value5
)

Tested in PHP 7.4.9

@brandonmcconnell
Copy link

@sayhicoelho Have you tried my approach above? It should work with associative and non-associative arrays, and be compatible with PHP 7+.

It also supports a depth parameter, so you can easily flatten only the top layer, the first N layers, or infinitely.

@graceman9
Copy link

@brandonmcconnell Using my sample data it gives not what I expected.
By the way, how to use it with unlimited $depth? array_flatten($r, 999) doesn't look good for me
Despite of that your function does the job of flattening, no doubt :) maybe flatten is not the right word because of ambiguity?

@sayhicoelho thanks for 7.x support!

echo json_encode(array_flatten($r, 9));
{
    "a": "value1",
    "c": "value1.1",
    "d": "value1.2",
    "e": "value2",
    "k": "value2.1",
    "m": "value2.2",
    "n": "value2.3",
    "o": "value3",
    "0": "first",
    "1": "second",
    "q": "value5"
}

@brandonmcconnell
Copy link

@graceman9 What data produces an unexpected result?

For infinite depth, just use -1

@graceman9
Copy link

@brandonmcconnell Have you noticed the difference?

{
    "a": "value1",
    "b_c": "value1.1",
}

and

{
    "a": "value1",
    "c": "value1.1",
}

@brandonmcconnell
Copy link

@graceman9 Oh you want the keys to be concatenated, so every key keeps the log of its original path. Yeah, you are correct that my version does not do that. I tried to follow the approach common in other languages. 🙂

@boedy
Copy link

boedy commented Apr 26, 2024

For a simple 2D array:

$multiDimArray = [[1, 2], [3, 4], [5, 6]];
$flatArray = array_reduce($multiDimArray, 'array_merge', []);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment