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);
2
  • Can't write code for different structure if alternate structure is unknown. Question is to broad and you need to identify various potential structures Commented Feb 15, 2016 at 14:55
  • Possible duplicate of 2d multidimensional array to 1d array in php Commented Feb 15, 2016 at 14:56

5 Answers 5

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);
}
Sign up to request clarification or add additional context in comments.

Comments

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
)

Comments

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

Comments

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
)

Comments

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

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.