askvity

How do you flatten a multi-dimensional array?

Published in PHP Arrays 4 mins read

To flatten a multi-dimensional array, you transform it into a single-dimensional array, effectively removing nested arrays. Several approaches can achieve this, each with its own trade-offs in terms of performance and readability.

Approaches to Flattening a Multi-Dimensional Array

Here are several methods to flatten a multi-dimensional array in PHP, along with examples:

1. Recursive Method

This approach uses a recursive function to traverse the array. If an element is an array, the function calls itself again. Otherwise, the element is added to the flattened array.

<?php

function flattenArrayRecursive(array $array): array {
    $result = [];
    foreach ($array as $element) {
        if (is_array($element)) {
            $result = array_merge($result, flattenArrayRecursive($element));
        } else {
            $result[] = $element;
        }
    }
    return $result;
}

$multiDimensionalArray = [1, [2, [3, 4]], 5, [6]];
$flattenedArray = flattenArrayRecursive($multiDimensionalArray);

print_r($flattenedArray); // Output: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )

?>

Explanation:

  • The flattenArrayRecursive function takes an array as input.
  • It iterates through each element of the array.
  • If an element is an array, it recursively calls itself on that element and merges the result with the $result array.
  • If an element is not an array, it's directly added to the $result array.
  • Finally, the function returns the flattened array.

2. Iterative Method using Stack

This method utilizes a stack to manage the elements to be processed, avoiding recursion.

<?php

function flattenArrayIterative(array $array): array {
    $result = [];
    $stack = [$array];

    while (!empty($stack)) {
        $current = array_pop($stack);

        if (is_array($current)) {
            foreach (array_reverse($current) as $element) {
                array_push($stack, $element);
            }
        } else {
            $result[] = $current;
        }
    }

    return array_reverse($result);
}

$multiDimensionalArray = [1, [2, [3, 4]], 5, [6]];
$flattenedArray = flattenArrayIterative($multiDimensionalArray);

print_r($flattenedArray); // Output: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )

?>

Explanation:

  • The flattenArrayIterative function takes an array as input.
  • It initializes a stack with the input array.
  • It iterates while the stack is not empty.
  • In each iteration, it pops an element from the stack.
  • If the element is an array, it pushes its elements onto the stack in reversed order to maintain the correct order in the final result.
  • If the element is not an array, it adds it to the $result array.
  • Finally, it reverses the $result array to get the correct order and returns it.

3. Using RecursiveIteratorIterator Class

This approach leverages PHP's built-in iterator classes for a more object-oriented solution.

<?php

function flattenArrayIterator(array $array): array {
    $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
    $result = [];
    foreach ($iterator as $element) {
        $result[] = $element;
    }
    return $result;
}

$multiDimensionalArray = [1, [2, [3, 4]], 5, [6]];
$flattenedArray = flattenArrayIterator($multiDimensionalArray);

print_r($flattenedArray); // Output: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )

?>

Explanation:

  • The flattenArrayIterator function takes an array as input.
  • It creates a RecursiveIteratorIterator instance, wrapping a RecursiveArrayIterator instance with the input array.
  • It iterates through the iterator, adding each element to the $result array.
  • Finally, it returns the flattened array.

4. Using array_walk_recursive()

This built-in function allows you to apply a callback function to each element of a multi-dimensional array recursively.

<?php

function flattenArrayWalkRecursive(array $array): array {
    $result = [];
    array_walk_recursive($array, function ($element) use (&$result) {
        $result[] = $element;
    });
    return $result;
}

$multiDimensionalArray = [1, [2, [3, 4]], 5, [6]];
$flattenedArray = flattenArrayWalkRecursive($multiDimensionalArray);

print_r($flattenedArray); // Output: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )

?>

Explanation:

  • The flattenArrayWalkRecursive function takes an array as input.
  • It initializes an empty $result array.
  • It uses array_walk_recursive to iterate through the array and apply a callback function to each element.
  • The callback function simply adds the element to the $result array.
  • Finally, it returns the flattened array.

5. Using array_reduce() and array_merge()

This approach leverages array_reduce() to accumulate the flattened array by merging subarrays recursively.

<?php

function flattenArrayReduce(array $array): array {
    return array_reduce($array, function ($result, $item) {
        if (is_array($item)) {
            return array_merge($result, flattenArrayReduce($item));
        } else {
            $result[] = $item;
            return $result;
        }
    }, []);
}

$multiDimensionalArray = [1, [2, [3, 4]], 5, [6]];
$flattenedArray = flattenArrayReduce($multiDimensionalArray);

print_r($flattenedArray); // Output: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )

?>

Explanation:

  • The flattenArrayReduce function takes an array as input.
  • It uses array_reduce to iterate through the array and accumulate the flattened array.
  • For each item, it checks if it's an array.
  • If it's an array, it recursively calls flattenArrayReduce on the item and merges the result with the accumulator.
  • If it's not an array, it adds the item to the accumulator.
  • The initial value of the accumulator is an empty array ([]).
  • Finally, it returns the flattened array.

Choosing the Right Method

The best approach depends on your specific needs:

  • Readability: array_walk_recursive and the recursive method can be more readable.
  • Performance: The iterative method using a stack is generally more performant than the recursive approach for deeply nested arrays, as it avoids function call overhead. RecursiveIteratorIterator might be slightly slower than other methods. array_reduce can be efficient but might be less readable for some.
  • Code style: RecursiveIteratorIterator aligns well with object-oriented programming paradigms.

Related Articles