Nicero
Nicero

Reputation: 4377

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")
        )
    )
);

Upvotes: -1

Views: 56

Answers (2)

mickmackusa
mickmackusa

Reputation: 48031

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);

Upvotes: 0

Andreas
Andreas

Reputation: 23968

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

Upvotes: 2

Related Questions