Question

situation

I have an array result returned from an Database call. In the example below, it fetches many Genres which can have many books. Using a join, the query pulls the books from each genre at the same time. Here is a hypothetical result set:

array(
    [0] => array (
        'id' => 1,
        'title' => 'ficton'
        'modules' => array(
            [0] => array(
                'other_id' => 1
                'other_title' => 'James Clavell'
            ),
            [1] => array(
                'other_id' => 2
                'other_title' => 'Terry Pratchett'
            ),
            [2] => array(
                'other_id' => 3
                'other_title' => 'Robert Ludlum'
            ),
        ),
    [1] => array (
        'id' => 2,
        'title' => 'non-ficton'
        'modules' => array(
            [1] => array(
                'other_id' => 5
                'other_title' => 'An excessive book of excessively interesting things'
            ),
            [2] => array(
                'other_id' => 6
                'other_title' => 'It\'s late, I can\'t think of what to put here'
            ),
        )
    )
)

Situation

What I would like to end up with is an array which contains only the modules as shown below:

array(
    [0] => array(
        'other_id' => 1
        'other_title' => 'James Clavell'
    ),
    [1] => array(
        'other_id' => 2
        'other_title' => 'Terry Pratchett'
    ),
    [2] => array(
        'other_id' => 3
        'other_title' => 'Robert Ludlum'
    ),
    [3] => array(
        'other_id' => 5
        'other_title' => 'An excessive book of excessively interesting things'
    ),
    [4] => array(
        'other_id' => 6
        'other_title' => 'It\'s late, I can\'t think of what to put here'
    )
)

Problem

Now, I have no problem achieving this through iteration but, feel there is a much better (undiscovered) means to achieving this.

Question

Is a shortcut to creating the desired result. The code I have so far is listed below and it's not a difficult situation to solve. I'm more just curious as to whether there is a much BETTER version of doing the following.

Ugly code that works

Here is a version of the code that 100% works but, features more iteration than I could care for.

$aryTemp = array();
foreach($aryGenres as $intKey => $aryGenre) {
    foreach($aryGenre['modules'] as $aryModule) {
        $aryTemp[] = $aryModule
    }
}

Attempt using array map

An attempt using array map and failing horribly

$aryTemp = array();
foreach($aryGenres as $intKey => $aryGenre) {
    $aryTemp[] = array_map(
        function($aryRun) { return $aryRun;
    },$aryGenre['modules']

}

I would love to be able to cut out the foreach loop as shown above.

Was it helpful?

Solution

PHP 5.6+:

$modules = array_merge(...array_column($arr, 'modules'));

# Allowing empty array
$modules = array_merge([], ...array_column($arr, 'modules'));

PHP 5.5:

$modules = call_user_func_array('array_merge', array_column($arr, 'modules'));

PHP ~5.4:

$modules = call_user_func_array(
    'array_merge',
    array_map(
        function ($i) {
            return $i['modules'];
        },
        $arr
    )
);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top