Traversing array to compare current and next key index - php

I am traversing an array to compare the current and next key index to check if the values are same.
I am making two arrays: First array when the condition is met -- value of current and next key index is same; second array is the remaining elements of an array.
But the problem is in the second array, I always get one element from the first array.
[special_days_nested_array] => Array
(
[0] => Array
(
[day_name] => Tue
[start_time] => 05:00 am
[end_time] => 08:00 pm
)
[1] => Array
(
[day_name] => Fri
[start_time] => 06:00 am
[end_time] => 10:00 pm
)
[2] => Array
(
[day_name] => Sat
[start_time] => 12:00 am
[end_time] => 08:54 pm
)
[3] => Array
(
[day_name] => Sun
[start_time] => 12:00 am
[end_time] => 08:54 pm
)
)
This is the array which I use for comparing the same value.
$j = 0;
foreach($data_set->special_days_nested_array as $key => $value){
if(($data_set->special_days_nested_array[$j]['start_time'] == $data_set->special_days_nested_array[$j+1]['start_time']) && ($data_set->special_days_nested_array[$j]['end_time'] == $data_set->special_days_nested_array[$j+1]['end_time']) ) {
//Days Array
$data_set->special_days_same_time_array[] = $data_set->special_days_nested_array[$j]['day_name'];
$data_set->special_days_same_time_array[] = $data_set->special_days_nested_array[$j+1]['day_name'];
//timings
$data_set->special_timings_same_time = $data_set->special_days_nested_array[$j]['start_time'].' - '.$data_set->special_days_nested_array[$j]['end_time'];
}
else{
$data_set->special_time_different_time_array[$data_set->special_days_nested_array[$key]['day_name']]['day_name'] = $data_set->special_days_nested_array[$key]['day_name'];
$data_set->special_time_different_time_array[$data_set->special_days_nested_array[$key]['day_name']]['start_time'] = $data_set->special_days_nested_array[$key]['start_time'];
$data_set->special_time_different_time_array[$data_set->special_days_nested_array[$key]['day_name']]['end_time'] = $data_set->special_days_nested_array[$key]['end_time'];
}
$j++;
}
Here i am traversing over the above array and comparing the current and next elements.
This is the array that I get in successful comparison.
[special_days_same_time_array] => Array
(
[0] => Sat
[1] => Sun
)
[special_timings_same_time] => 12:00 am - 08:54 pm
This is the array that I get from the else condition:
[special_time_different_time_array] => Array
(
[Tue] => Array
(
[day_name] => Tue
[start_time] => 05:00 am
[end_time] => 08:00 pm
)
[Fri] => Array
(
[day_name] => Fri
[start_time] => 06:00 am
[end_time] => 10:00 pm
)
[Sun] => Array
(
[day_name] => Sun
[start_time] => 12:00 am
[end_time] => 08:54 pm
)
)
In this array, the first two elements are correct, but the third element I get is not correct.
I am not able to figure out the exact problem.

You have a problem with bound element of your array because of incorrect loop implementation. That is because for the last element there is no j+1th element so you will always enter else branch of condition.
Also you mix regular for syntax with foreach syntax. I would recommend you to use simple and straightforward for operator for this case:
for($j = 0; $j < count(data_set->special_days_nested_array)-1; $j++){
if(($data_set->special_days_nested_array[$j]['start_time'] == $data_set->special_days_nested_array[$j+1]['start_time']) && ($data_set->special_days_nested_array[$j]['end_time'] == $data_set->special_days_nested_array[$j+1]['end_time']) ) {
//Days Array
$data_set->special_days_same_time_array[] = $data_set->special_days_nested_array[$j]['day_name'];
$data_set->special_days_same_time_array[] = $data_set->special_days_nested_array[$j+1]['day_name'];
//timings
$data_set->special_timings_same_time = $data_set->special_days_nested_array[$j]['start_time'].' - '.$data_set->special_days_nested_array[$j]['end_time'];
}
else{
$data_set->special_time_different_time_array[$data_set->special_days_nested_array[$j]['day_name']]['day_name'] = $data_set->special_days_nested_array[$j]['day_name'];
$data_set->special_time_different_time_array[$data_set->special_days_nested_array[$j]['day_name']]['start_time'] = $data_set->special_days_nested_array[$j]['start_time'];
$data_set->special_time_different_time_array[$data_set->special_days_nested_array[$j]['day_name']]['end_time'] = $data_set->special_days_nested_array[$j]['end_time'];
}
}

Related

Merge & Find SUM of two associative array - PHP

I have two associative arrays with time and total booking for that particular time.i need to merge this 2 arrays by adding booking count for corresponding timing.
Array 1:
Array
(
[0] => stdClass Object
(
[time] => 03:00 PM - 04:30 PM
[booked] => 3
)
[1] => stdClass Object
(
[time] => 05:00 PM - 06:30 PM
[booked] => 2
)
)
Array 2:
Array
(
[0] => stdClass Object
(
[time] => 03:00 PM - 04:30 PM
[booked] => 3
)
[1] => stdClass Object
(
[time] => 07:00 PM - 08:30 PM
[booked] => 1
)
)
This is the output i need to generate..tried many ways to merge with finding sum but i can only merge this arrays...
Array
(
[0] => stdClass Object
(
[time] => 03:00 PM - 04:30 PM
[booked] => 6
)
[1] => stdClass Object
(
[time] => 05:00 PM - 06:30 PM
[booked] => 2
)
[2] => stdClass Object
(
[time] => 07:00 PM - 08:30 PM
[booked] => 1
)
)
You can use array_merge with foreach and array_key_exists
$a3 = array_merge($a1,$a2);
$r = [];
foreach($a3 as $v){
array_key_exists($v->time, $r)
?
($r[$v->time]->booked += $v->booked)
:
($r[$v->time] = $v);
}
print_r(array_values($r)); // re-arrange the array keys
Working example : https://3v4l.org/JAZ4d

Search array of dates does not return result

Hello I am trying to search for an hour based on the current date with the following function:
$key = array_search($todayday, array_column($days, 'date', 'hours'));
Where $todayday is equal to today day which comes from the sever day date.
the Array $days is:
Array
(
[0] => Array
(
[date] => 01
[hours] => 0
)
[1] => Array
(
[date] => 02
[hours] => 8
)
[2] => Array
(
[date] => 03
[hours] => 16
)
[3] => Array
(
[date] => 04
[hours] => 24
)
[4] => Array
(
[date] => 05
[hours] => 32
)
[5] => Array
(
[date] => 06
[hours] => 40
)
[6] => Array
(
[date] => 07
[hours] => 40
)
... etc....
while $todaydate is equal to 1,2,3,4,5 it works. but for 6 and 7 does not return anything. Any help is welcome to resolve this issue. Thanks
I suspect that since date = 6 and 7 have the same value of hours this is why it does not return anything but the question is how to return it actually.
Your supposition is correct, you can not have duplicate keys. Use the key from the search and then access hours:
$key = array_search($todayday, array_column($days, 'date'));
$hours = $days[$key]['hours'];
Or shorter:
$hours = $days[array_search($todayday, array_column($days, 'date'))]['hours'];
In the case where the indexes are not 0 based and sequential, use array_values() to re-index:
$days = array_values($days);
$key = array_search($todayday, array_column($days, 'date'));
$hours = $days[$key]['hours'];

How to Group PHP Array Based On Year with Nested Array

My Current PHP Array Outputs like this:
Array
(
[0] => Array
(
[year] => 2015
[month] => November
)
[1] => Array
(
[year] => 2015
[month] => October
)
[2] => Array
(
[year] => 2015
[month] => September
)
[3] => Array
(
[year] => 2015
[month] => August
)
[4] => Array
(
[year] => 2015
[month] => July
)
[5] => Array
(
[year] => 2015
[month] => June
)
[6] => Array
(
[year] => 2015
[month] => May
)
[7] => Array
(
[year] => 2015
[month] => April
)
[8] => Array
(
[year] => 2015
[month] => March
)
[9] => Array
(
[year] => 2015
[month] => February
)
[10] => Array
(
[year] => 2015
[month] => January
)
[11] => Array
(
[year] => 2014
[month] => December
)
[12] => Array
(
[year] => 2014
[month] => November
)
[13] => Array
(
[year] => 2014
[month] => October
)
[14] => Array
(
[year] => 2014
[month] => September
)
[15] => Array
(
[year] => 2014
[month] => August
)
[16] => Array
(
[year] => 2014
[month] => July
)
)
I want to sort the above Array and group them based on the Year. The Array I want to convert the above is to get like this:
Array (
[0] => Array
(
[yearGroup] => “2015”
[dates] => Array
(
[0] => Array
(
[year] => 2015
[month] => November
)
[1] => Array
(
[year] => 2015
[month] => October
)
…etc..etc…
)
)
[1] => Array
(
[yearGroup] => 2014
[dates] => Array
(
[0] => Array
(
[year] => 2014
[month] => December
)
[1] => Array
(
[year] => 2014
[month] => November
)
…etc..etc…
)
)
)
This is the code I have tried so far:
$calendar = // ..... The Array Above .....;
$sidebarCalendar = array();
$currentYear = '';
$i = 0;
foreach ($calendar as $date) {
if ($currentYear != $date['year']) {
$currentYear = $date['year'];
$i++;
$tempYearDates = array();
$j = 0;
$tempYearDates[$j] = array(
'year' => $date['year'],
'month' => $date['month']
);
$j++;
// Add to Array
$sidebarCalendar[$i] = array (
'yearGroup' => $date['year'],
'dates' => $tempYearDates
);
}
else {
$tempYearDates = array(
'year' => $date['year'],
'month' => $date['month']
);
// Locate the Array Tree
$currentParent = $sidebarCalendar[$i];
$currentArray = $currentParent['dates'];
$currentArray[$j] = $tempYearDates;
$j++;
}
}
But the above outputs incomplete array like this:
Array
(
[1] => Array
(
[yearGroup] => 2015
[dates] => Array
(
[0] => Array
(
[year] => 2015
[month] => November
)
)
)
[2] => Array
(
[yearGroup] => 2014
[dates] => Array
(
[0] => Array
(
[year] => 2014
[month] => December
)
)
)
)
Can someone point out what I have got wrong here please? If there is a better way to do the same instead of the above method, please do guide me there please…
You could use some of the builtin PHP's array functions to solve this issue. First thing you want to do is get all the unique years in that array, so you could do:
$years = array_unique(array_map(function($item) { return $item['year']; }, $calendar));
Here, I've used array_map to get an array containing only the year property for each item, and fed it to the array_unique function to get only unique values.
Next thing you could do is iterate through all the years, and populate another array, something like this:
$grouped = [];
foreach($years as $year) {
$grouped[$year] = array_filter($calendar, function($item) use ($year) { return $item['year'] === $year; });
}
This way you'll get a key for each year in the grouped variable, and each key will contain a subarray composed only of the elements of calendar satisfying the array_filter condition.
I'm sure there are better / more optimized ways of doing this (maybe using array_walk or array_reduce?) and I encourage you to find those! Still, remember that there are many array functions builtin in PHP, read their documentation and learn when to use them, they'll be of great help!
Edit: I realize that the output of my solution is not exactly what you're expecting, but it's very easily adaptable. I myself prefer using keyed arrays (maps?) whenever possible in place of regular arrays with properties, but to each their own!
$grouped = [];
foreach($years as $year) {
$grouped[] = [
'yearGroup' => $year,
'dates' => array_filter($calendar, function($item) use ($year) { return $item['year'] === $year; })
];
}
Edit 2: Sometimes I forget how to PHP.

How to show data from array according to index using foreach loop

what i need
i need to append data according index in php using foreach loop.
php code
foreach($data[$k]['agenda'] as $key=>$value)
{
if($key >1)
{
print_r($data[$k]['agenda'][$key]);
}
}
array structure
Array
(
[title] => The First 10 Steps to Taking Your Retail Business Online
[description] =>
[Start_time] => 10:15 AM
[end_time] => 11:45 AM
[days] => 2014-02-05
)
Array
(
[title] => Tricks
[description] =>
[Start_time] => 11:45 AM
[end_time] => 01:00 PM
[days] => 2014-02-05
)
Array
(
[title] => Lunch and Networking
[description] =>
[Start_time] => 01:00 PM
[end_time] => 02:00 PM
[days] => 2014-02-05
)
Array
(
[title] => Launch of Online Sellers Association of India (OSAI)
[description] =>
[Start_time] => 06:15 PM
[end_time] => 06:15 PM
[days] => 2014-02-07
)
show the data in view
if($data[$k]['agenda'])
{
$content .='<p><span>Topic:</span><b>'.$data[$k]['agenda'][$key]['title'].'</b></p>';
}
output is shown
topic: Launch of Online Sellers Association of India (OSAI)
instead of o/p should
if its from 2 index
topic : Lunch and Networking
and so on from index greater then 2.
You need to append data inside a loop. Now, $key has only the last value.
$content = ''; // if $content doesn't exist yet, define
foreach($data[$k]['agenda'] as $key => $value) {
if($key > 1) { // do you need this condition?
$content .= '<p><span>Topic:</span><b>' . $data[$k]['agenda'][$key]['title'] . '</b></p>';
}
}

How do I sort a multi-dimensional array by time values in PHP?

I'm doing a school project and I have a multi-dimensional array having start_time and end_time of courses.
I already sorted the array by day, but I also want to sort the array by time. Such that the lowest start_time is the first element of the array.
This is how my array is at the moment:
Array (
[0] => Array (
[courseID] => comp345
[lectureID] => ss
[day] => monday
[stime] => 18:20
[etime] => 20:30
[term] => winter
[year] => 2014
)
[1] => Array (
[courseID] => comp275
[lectureID] => gg
[day] => monday
[stime] => 12:15
[etime] => 15:16
[term] => winter
[year] => 2014
)
)
I was wondering if there are any pre-defined functions to do that or if i need to create a new specific function for this task .
I can access the values of the start_time like this :
foreach ($array as $element)
{
$start_time = (substr($element['stime'], 0, 5));
}
This will return the time in this format : 08:20
It works the same way as normal numbers when comparing such as :
08:20 < 10:15 = true
08:20 > 10:15 = false
Get the stime items, convert them to a timestamp and sort, sorting the original array on that:
All versions:
array_multisort(array_map(function($v) {
return strtotime($v['stime']);
}, $array), SORT_ASC, $array);
PHP >= 5.5.0:
array_multisort(array_map('strtotime', array_column($array, 'stime')), SORT_ASC, $array);
Alternate:
foreach ($array as $k => $v) {
$stime[$k] = strtotime($v['stime']);
}
array_multisort($stime, SORT_ASC, $array);
Add the unix timestamp with mktime to your array and sort by that timestamp. The unix timestamp is the number of second since 1970, so it is an integer and hence easy to sort.
Take a look at this reference question about sorting in PHP.
As you have
Array (
[0] => Array ( [courseID] => comp345 [lectureID] => ss
[day] => monday
[stime] => 18:20
[etime] => 20:30
[term] => winter
[year] => 2014 )
[1] => Array ( [courseID] => comp275 [lectureID] => gg
[day] => monday [stime] => 12:15
[etime] => 15:16 [term] => winter
[year] => 2014 ) )
Something like this should do it:
Go through array, add 'unixtimestamp' = mktime($el['hour'], $el['minute'], 0, 0, 0, $el['year'])
function sortByOrder($a, $b) {
return $a['unixtimestamp'] - $b['unixtimestamp'];
}
usort($myArray, 'sortByOrder');

Categories