Merge & Find SUM of two associative array - PHP - 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

Related

Creating a weekly array with multiple entries for each day

I have a MySQL query that returns a dump of data like so (duplicates expected and needed for other columns that are excluded for this question):
SessionID  DayofWeek SessionDetails Description
1 Sunday 1:00 PM Foo
1 Sunday 1:00 PM Foo
1 Sunday 1:00 PM Foo
1 Sunday 1:00 PM Foo
2 Monday 10:00 AM Foo
2 Monday 10:00 AM Foo
2 Monday 10:00 AM Foo
2 Monday 10:00 AM Foo
3 Monday 7:00 PM Barr
3 Monday 7:00 PM Barr
3 Monday 7:00 PM Barr
3 Monday 7:00 PM Barr
I am trying to create an array for each day and only store the different session/times once in it, e.g.,
Sunday => Array (
[SessionID] => 1
[SessionDetails] => 1:00 PM
[Description] => Foo
)
Monday=> Array (
[SessionID] => 2
[SessionDetails] => 10:00 AM
[Description] => Foo
[SessionID] => 3
[SessionDetails] => 7:00 PM
[Description] => Bar
)
I am setting a blank array for each day before my foreach ($sqlresults as $row) loop, like $sunday=array(); $monday=array(); etc.
Then inside the loop I am doing:
if (!in_array($row['SessionID'],$sunday)){
$sunday[]=array($row['SessionID'],$row['Description'], $row['SessionDetails']);
}
It sort-of-works but it's not checking the if (!in_array) part right and it's adding every single (duplicate) SessionID as a new array e.g.,
print_r($sunday)
Array
(
[0] => Array
(
[0] => 1
[1] => Foo
[2] => 1 PM
)
[1] => Array
(
[0] => 1
[1] => Foo
[2] => 1 PM
)
[2] => Array
(
[0] => 1
[1] => Foo
[2] => 1 PM
)
[3] => Array
(
[0] => 1
[1] => Barr
[2] => 1 PM
)
[4] => Array
(
[0] => 2
[1] => Barr
[2] => 10 AM
)
etc...
I tried to check the sessionID inside the array before adding to it:
if (!in_array($row['SessionID'][],$sunday)){
But "Fatal error: Cannot use [] for reading"
So I tried:
if (!in_array($sunday[$row['SessionID']],$sunday)){
But "Notice: Undefined offset: 1"
I tried setting it to associative values:
if (!in_array($row['SessionID'],$sunday)){
$sunday[]=array("SessionID"=>($row['SessionID']),"Description"=>($row['Description']), "Time"=>($row['SessionDetails']));
}
Same problem, except the array is easier to read:
[0] => Array
(
[SessionID] => 1
[Description] => Foo
[Time] => 1 PM
)
[1] => Array
(
[SessionID] => 1
[Description] => Foo
[Time] => 1 PM
)
TLDR: How can I get it to check the index [SessionID] before trying to add to the day array?
Here's a simple way to do it using array_unique.
$result = [];
foreach (array_unique($rows, SORT_REGULAR) as $row) {
$result[$row['DayofWeek']][] = $row;
}
You can run the code here.

How to sort time by meridiem(AM/PM) in PHP

I have time with meridiem(AM/PM).
For example,
I have time
Array
(
[0] => 11:00 AM
[1] => 6:00 AM
)
So after sorting:
Array
(
[0] => 6:00 AM
[1] => 11:00 AM
)
And if I have:
Array
(
[0] => 11:00 AM
[1] => 6:00 PM
)
So sorting will be:
Array
(
[0] => 11:00 AM
[1] => 6:00 PM
)
I have tried with
sort($arr,SORT_LOCALE_STRING);
and
sort($arr,SORT_NUMERIC);
But not worked.
Any solution for this? Thanks.
Try this code.
usort($array, function($a, $b) {
return (strtotime($a) > strtotime($b));
});

Combine intersecting keys and values in 2 arrays

I'm running through all of the array functions on php.net and unable to figure this out.
Essentially I want to take these two arrays:
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[credit] => 1000.00
)
[1] => stdClass Object
(
[month] => September
[year] => 2015
[credit] => 200.00
)
)
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[debit] => 2000.00
)
[1] => stdClass Object
(
[month] => August
[year] => 2015
[debit] => 50.00
)
)
...and have the output look like this:
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[credit] => 1000.00
[debit] => 2000.00
)
[1] => stdClass Object
(
[month] => September
[year] => 2015
[credit] => 200.00
[debit] => 0
)
[2] => stdClass Object
(
[month] => August
[year] => 2015
[credit] => 0
[debit] => 50.00
)
)
I'm looked to merge "month" and "year" and combine the other keys, using a default value if the key doesn't exist. Any guidance?
Assuming $debits and $credits are the arrays shown in your question, I would approach it like this:
First loop over the credits, inserting them into the new "combined" array and adding a default value for debit as you go.
foreach ($credits as $credit) {
$credit->debit = 0.00; // provide a default value for debit
$combined[$credit->year . $credit->month] = $credit;
}
Then loop over the debits. Since there is the possibilities that entries will already be there from credits, there needs to be a check for this. This part should update existing values inserted from credits, or insert new values if there is no existing value.
foreach ($debits as $debit) {
if (isset($combined[$debit->year . $debit->month])) {
// update the debit if the entry already exists
$combined[$debit->year . $debit->month]->debit = $debit->debit;
} else {
// otherwise create a new entry with a default value for credit
$debit->credit = 0.00;
$combined[$debit->year . $debit->month] = $debit;
}
}
// If you need the results to be numerically indexed, you can use array_values
$numerically_indexed = array_values($combined);

Traversing array to compare current and next key index

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'];
}
}

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>';
}
}

Categories