Reputation: 97
I have an array of events containing a title, start time, end time, start date.
I'm looping through all of the results currently with:
foreach ($events as $event) {
echo $event['title'];
}
Which lists the items absolutely fine.
Is there a way I can GROUP the below array into months per year? Eg.
May 2018
July 2018
January 2019
My sample input rows:
Array
(
[title] => Title 1
[start_time] => 09:00
[end_time] => 17:00
[start_date] => 2017-05-25
)
Array
(
[title] => Title 2
[start_time] => 09:00
[end_time] => 17:00
[start_date] => 2018-05-25
)
Array
(
[title] => Title 3
[start_time] => 09:00
[end_time] => 17:00
[start_date] => 2018-05-27
)
Array
(
[title] => Title 3
[start_time] => 09:00
[end_time] => 17:00
[start_date] => 2018-07-15
)
Array
(
[title] => Title 4
[start_time] => 09:00
[end_time] => 17:00
[start_date] => 2019-01-2
)
Upvotes: 0
Views: 906
Reputation: 47894
Use one simple loop to group and push titles into each group, and another loop to print your formatted text.
Code: (Demo)
$result = [];
foreach ($array as $row) {
$key = date('F Y', strtotime($row['start_date']));
$result[$key][] = $row['title'];
}
foreach ($result as $FY => $titles) {
printf("%s\n- %s\n\n", $FY, implode("\n- ", $titles));
}
Upvotes: 0
Reputation: 381
Certainly! First you need to make sure your array is sorted properly. Which it's best to use PHP's usort
function for this. It accepts the array to sort and a function for which to compare the elements.
usort($array, function ($a, $b) {
$aDate = strtotime($a['start_date']);
$bDate = strtotime($b['start_date']);
if ($aDate == $bDate) {
return 0;
}
return ($aDate < $bDate) ? -1 : 1;
});
More on usort
can be found here.
Once the array is properly sorted, then you can start to create sections in your code. A simple way to handle this is to create a variable that will track the section that you want to create. And when the section changes then it will output it in the loop. Obviously this only works if you have previously sorted the array, which was why I included the previous section.
$month = null;
foreach ($events as $event) {
$newMonth = date('F', strtotime($event['start_date']) );
if($month != $newMonth) {
$month = $newMonth;
echo $month;
}
echo $event['title'];
}
A couple of other function references (strtotime
, date
).
Upvotes: 0
Reputation: 1
Writing out JoshKisb's suggestion:
$monGrp = array();
// build an array based on YYYY-MM since that is what we're grouping by
foreach ($events as $event) {
$monGrp[substr($event['start_date'], 0, 7) . '-01'][] = $event;
}
// sort by the key so it is the correct date order
ksort($monGrp);
// now loop through the grouped array and write the desired output
foreach ($monGrp as $mon => $grpEvents) {
echo "<p>" . date("F Y", strtotime($mon));
foreach ($grpEvents as $event) {
echo " - " . $event['title'] . "<br>\n";
}
}
Upvotes: 0
Reputation: 11313
One possible way to achieve what you want consists of the following steps:
Code:
/* ----- Group the data ----- */
# Create an array to store the data.
$grouped = [];
# Iterate over every event.
foreach ($events as $event) {
# Format and save the date as 'Month Year'.
$monthYear = date("F Y", strtotime($event["start_date"]));
# Define the key of the object as as an array, if not already defined.
$grouped[$monthYear] = $grouped[$monthYear] ?? [];
# Insert the title to the array corresponding to the formatted date.
$grouped[$monthYear][] = $event["title"];
}
/* ----- Print the data ----- */
# Iterate over every key - value.
foreach ($grouped as $key => $value) {
# Print the 'Month Year' key.
echo $key . "\n";
# Iterate over every title and print it.
foreach ($value as $title) echo "- $title\n";
# Separate each group with an empty line.
echo "\n";
}
Example:
Check out this example for a live demonstration.
Note:
The line $grouped[$monthYear] = $grouped[$monthYear] ?? []
works for PHP7+
. If you use an older version, you can supplant it with the following:
# Check whether the key is not set.
if (!isset($grouped[$monthYear])) $grouped[$monthYear] = [];
Upvotes: 0
Reputation: 3414
Something as per code below should work. You will have to group them by year, and month and then sort them desc
$dates = [];
foreach($arrayOfDates as $event){
$timestamp = strtotime($event['start_date']);
$dateSort = date('Y-m', $timestamp);
$dates[$dateSort][] = ['title' => $event['title']];
}
krsort($dates);
foreach($dates as $key => $values){
echo $key;
foreach($values as $value){
echo "* ". $value['title'];
}
}
Upvotes: 3