-1

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")
        )
    )
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Nicero
  • 4,181
  • 6
  • 30
  • 52

2 Answers2

2

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

Andreas
  • 23,610
  • 6
  • 30
  • 62
0

You can use functional-style programming to group and re-index the items subarray without declaring any temporary variables in the global space.

As you iterate each row of $array['items'], use temporary keys for grouping and push rows into their respective group. When finished grouping, re-index the data with array_values().

Code: (Demo)

$array = [
    "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"]
    ]
];

$array["items"] = array_values(
    array_reduce(
        $array["items"],
        function ($carry, $row) {
            $carry[$row["end_date"]]["data"] = $row["end_date"];
            $carry[$row["end_date"]][] = $row;
            return $carry;
        }
    )
);
var_export($array);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136