Search code examples
phparraysmultidimensional-arraygroupingsub-array

Group row data of a 2d array by a column and push another column as subarray items per group


I have this multidimentional array in PHP

Array (
[4570] => Array
    (
        [id] => 1647
        [date] => 2017-13
    )

[4571] => Array
    (
        [id] => 1647
        [date] => 2017-14
    )

[4573] => Array
    (
        [id] => 1705
        [date] => 2017-15
    )

[4574] => Array
    (
        [id] => 1705
        [date] => 2017-15
    )
 )

I want to make an array like this:

Array
(
  [2017-13] => Array
  (
     all the ids associated with 2017-13
  )

  [2017-14] => Array
  (
     all the ids associated with 2017-14
     [id]
     [id]
     ...
  )
)

etc


Solution

  • This probably is what you are looking for:

    <?php
    $input = [
        4570 => [
            'id' => 1647,
            'date' => '2017-13'
        ],
        4571 => [
            'id' => 1647,
            'date' => '2017-14'
        ],
        4573 => [
            'id' => 1705,
            'date' => '2017-15'
        ],
        4574 => [
            'id' => 1705,
            'date' => '2017-15'
        ]
    ];
    $output = [];
    
    array_walk($input, function($entry) use (&$output) {
        $output[$entry['date']][] = $entry['id'];
    });
    
    print_r($output);
    

    The output of above code obviously is:

    Array
    (
        [2017-13] => Array
            (
                [0] => 1647
            )
    
        [2017-14] => Array
            (
                [0] => 1647
            )
    
        [2017-15] => Array
            (
                [0] => 1705
                [1] => 1705
            )
    
    )
    

    If you want to prevent ids getting added twice (as in the example for key 2017-15), you simply add a condition:

    array_walk($input, function($entry) use (&$output) {
        if (   ! isset($output[$entry['date']]) 
            || ! in_array($entry['id'], $output[$entry['date']])) {
            $output[$entry['date']][] = $entry['id'];
        }
    });