phparraysmultidimensional-arraygroupingsub-array

Group array items by key value adding an associative element with the grouped values


Having the following array:

$a = [
    "category" => "Music", 
    "items" => [
        ["ID" => "1", "start_date" => "2018-11-20", "end_date" => "2018-11-28"],
        ["ID" => "2", "start_date" => "2018-11-22", "end_date" => "2018-11-28"],
        ["ID" => "3", "start_date" => "2018-11-26", "end_date" => "2018-11-30"],
        ["ID" => "4", "start_date" => "2018-11-27", "end_date" => "2018-11-31"],
        ["ID" => "4", "start_date" => "2018-11-29", "end_date" => "2018-11-31"]
    ]
];

I would like to 'group' the arrays by end_date but not using end_date as key as I saw in other posts or forums, but by adding the value of end_date as a value of a new key.

So that the expected result would be:

array(
    "category" => "Music",
    "items" => array(
        array(
            "date" => "2018-11-28",
            array("ID" => "1", "start_date" => "2018-11-20", "end_date" => "2018-11-28"),
            array("ID" => "2", "start_date" => "2018-11-22", "end_date" => "2018-11-28"),
        ),
        array(
            "date" => "2018-11-30",
            array("ID" => "3", "start_date" => "2018-11-26", "end_date" => "2018-11-30")
        ),
        array(
            "date" => "2018-11-31",
            array("ID" => "4", "start_date" => "2018-11-27", "end_date" => "2018-11-31"),
            array("ID" => "4", "start_date" => "2018-11-29", "end_date" => "2018-11-31")
        )
    )
);

Solution

  • Loop the array and build an temporary associative array with the end date as the key.
    Then copy the original array and unset the 'items' and add the new temporary array values.

    $a = array("category" => "Music", 
            "items" => array(
                array("ID" => "1", "start_date" => "2018-11-20", "end_date" => "2018-11-28"),
                array("ID" => "2", "start_date" => "2018-11-22", "end_date" => "2018-11-28"),
                array("ID" => "3", "start_date" => "2018-11-26", "end_date" => "2018-11-30"),
                array("ID" => "4", "start_date" => "2018-11-27", "end_date" => "2018-11-31"),
                array("ID" => "4", "start_date" => "2018-11-29", "end_date" => "2018-11-31")
            )
    );
    
    foreach($a['items'] as $item){
        $new[$item['end_date']]['date'] = $item['end_date'];
        $new[$item['end_date']][] = $item;
    }
    $res = $a;
    unset($res['items']);
    $res['items'] = array_values($new);
    
    
    var_dump($res);
    

    Output:

    array(2) {
      ["category"]=>
      string(5) "Music"
      ["items"]=>
      array(3) {
        [0]=>
        array(3) {
          ["date"]=>
          string(10) "2018-11-28"
          [0]=>
          array(3) {
            ["ID"]=>
            string(1) "1"
            ["start_date"]=>
            string(10) "2018-11-20"
            ["end_date"]=>
            string(10) "2018-11-28"
          }
          [1]=>
          array(3) {
            ["ID"]=>
            string(1) "2"
            ["start_date"]=>
            string(10) "2018-11-22"
            ["end_date"]=>
            string(10) "2018-11-28"
          }
        }
        [1]=>
        array(2) {
          ["date"]=>
          string(10) "2018-11-30"
          [0]=>
          array(3) {
            ["ID"]=>
            string(1) "3"
            ["start_date"]=>
            string(10) "2018-11-26"
            ["end_date"]=>
            string(10) "2018-11-30"
          }
        }
        [2]=>
        array(3) {
          ["date"]=>
          string(10) "2018-11-31"
          [0]=>
          array(3) {
            ["ID"]=>
            string(1) "4"
            ["start_date"]=>
            string(10) "2018-11-27"
            ["end_date"]=>
            string(10) "2018-11-31"
          }
          [1]=>
          array(3) {
            ["ID"]=>
            string(1) "4"
            ["start_date"]=>
            string(10) "2018-11-29"
            ["end_date"]=>
            string(10) "2018-11-31"
          }
        }
      }
    }
    

    https://3v4l.org/foKL7