0

Is there a PHP array function to compress the following array structure;

array:2 [▼
  0 => array:2 [▼
    0 => {#90 ▶}
    1 => {#91 ▶}
  ]
  1 => array:5 [▼
    0 => {#92 ▶}
    1 => {#93 ▶}
    2 => {#94 ▶}
    3 => {#95 ▶}
    4 => {#96 ▶}
  ]
]

In to something like this;

array:7 [▼
    0 => {#90 ▶}
    1 => {#91 ▶}
    3 => {#92 ▶}
    4 => {#93 ▶}
    5 => {#94 ▶}
    6 => {#95 ▶}
    7 => {#96 ▶}
  ]
]

Sorry this is a dd (die and dump) using Laravel but I think you get the general idea of what I am trying to achieve.

Also note, this may not always be the structure of the passed in data. Sometimes it will only be a single dimension array. So this will cause an error;

$domain->questions = call_user_func_array('array_merge', $domain->questions);
mikelovelyuk
  • 4,042
  • 9
  • 49
  • 95
  • Can't write code for different structure if alternate structure is unknown. Question is to broad and you need to identify various potential structures – charlietfl Feb 15 '16 at 14:55
  • Possible duplicate of [2d multidimensional array to 1d array in php](http://stackoverflow.com/questions/6914105/2d-multidimensional-array-to-1d-array-in-php) – Chris Feb 15 '16 at 14:56

5 Answers5

1

This seems to work but will only serve it's purpose if the array is 2 levels deep. Fortunately that's all I need for now;

if(is_array($questions[0])) {
    $questions = call_user_func_array('array_merge', $questions);
}
mikelovelyuk
  • 4,042
  • 9
  • 49
  • 95
0

Here's a solution for one- and two-dimensional arrays:

<?php
$input = array(
    array(
        0 => '#90',
        1 => '#91',
    ),
    array(
        0 => '#92',
        1 => '#93',
        2 => '#94',
        3 => '#95',
        4 => '#96',
    )
);

$newarray = array();
foreach($input as $items) {
    if (is_array($items)) foreach ($items as $item) {
        $newarray[] = $item;
    } else {
        $newarray[] = $items;
    }
}

echo '<pre>'; print_r($newarray); echo '</pre>';

And here's the same foreach logic with a mixed array (array of arrays and array of items):

<?php

$input = array(
    0 => '#90',
    array(
        0 => '#91',
        1 => '#92',
    ),
    4 => '#93',
    5 => '#94',
    6 => '#95',
    7 => '#96',
);

$newarray = array();
foreach($input as $items) {
    if (is_array($items)) foreach ($items as $item) {
        $newarray[] = $item;
    } else {
        $newarray[] = $items;
    }
}
echo '<pre>'; print_r($newarray); echo '</pre>';

So the foreach logic is useable whether the input array is one-dimensional, two-dimensional or mixed.

The result, in both cases, will be:

Array
(
[0] => #90
[1] => #91
[2] => #92
[3] => #93
[4] => #94
[5] => #95
[6] => #96
)

hherger
  • 1,660
  • 1
  • 10
  • 13
0

Because you don't know if an array contains sub items or not, you could try something like this:

function flatten($array) {
    // If this is already an empty array or a flat array, just return it
    if (empty($array) || ! is_array($array[0])) {
        return $array;
    }

    // just merge all sub-arrays into a single array
    $flat = [];
    foreach ($array as $item) {
        $flat = array_merge($flat, $item)
    }
    return $flat;
}

Another option which would be slower (but more resilient to different formats) would be:

function flatten($array) {
    // If this is already an empty array just return it
    if (empty($array)) {
        return $array;
    }

    // just add all sub-items into a single array
    $flat = [];
    foreach ($array as $item) {
        if (is_array($item)) {
           $flat = array_merge($flat, flatten($item));
        } else {
           $flat[] = $item;
        }
    }
    return $flat;
}

This will do a 'deep' flattening of arrays, but as I said - will be slower

samlev
  • 5,852
  • 1
  • 26
  • 38
0

Try this simple function:

function flatArray($array)
{
    $retval = array();

    foreach ($array as $val) {
        if (is_array($val))
            $retval = array_merge($retval, flatArray($val));
        else
            $retval[] = $val;
    }
    return $retval;
}

Then:

$array1 = [['#90', '#91'], ['#92', '#93', '#94', '#95', '#96']];
$array2 = ['#82', '#83', '#84', '#85', '#86'];
$array3 = [['#90', '#91', ['100', '101']], ['#92', '#93', '#94', '#95', '#96']];

print_r(flatArray($array1));
print_r(flatArray($array2));
print_r(flatArray($array3));

will output:

Array
(
    [0] => #90
    [1] => #91
    [2] => #92
    [3] => #93
    [4] => #94
    [5] => #95
    [6] => #96
)

and

Array
(
    [0] => #82
    [1] => #83
    [2] => #84
    [3] => #85
    [4] => #86
)

and - for array3 (three levels):

Array
(
    [0] => #90
    [1] => #91
    [2] => 100
    [3] => 101
    [4] => #92
    [5] => #93
    [6] => #94
    [7] => #95
    [8] => #96
)

3v4l.org demo

Edit:

Added recursive call: by this way, you can flat even multi-nested arrays

fusion3k
  • 11,568
  • 4
  • 25
  • 47
0

I think this does what you want

<?php

$tester = [
    ['90', '91'],
    ['92', '93', '94', '95', '96']
];

$tester2 = array_merge($tester[0], $tester[1]);

print_r($tester);
print_r($tester2);

produces this output:

Array
(
    [0] => Array
        (
            [0] => 90
            [1] => 91
        )

    [1] => Array
        (
            [0] => 92
            [1] => 93
            [2] => 94
            [3] => 95
            [4] => 96
        )

)
Array
(
    [0] => 90
    [1] => 91
    [2] => 92
    [3] => 93
    [4] => 94
    [5] => 95
    [6] => 96
)
Jeff
  • 9,076
  • 1
  • 19
  • 20