Counting arrays based on specific object property - php

Is it possible count arrays based on specific object property?
[0] => stdClass Object
(
[ID] => 12345
[Name] => TEST 1
[position] => POS 1
[2023-02-01] => 22:00 - 06:00
[2023-02-02] => REST DAY
[2023-02-03] => 14:00 - 22:00
[2023-02-04] => 14:00 - 22:00
[2023-02-05] => 14:00 - 22:00
[2023-02-06] => 22:00 - 06:00
[2023-02-07] => REST DAY
[2023-02-08] => 14:00 - 22:00
[2023-02-09] => 22:00 - 06:00
[2023-02-10] => DAY OFF
[2023-02-11] => 14:00 - 22:00
[2023-02-12] => -
[2023-02-13] => -
[2023-02-14] => -
[2023-02-15] => -
)
[1] => stdClass Object
(
[ID] => 67890
[Name] => TEST 2
[position] => POS 2
[2023-02-01] => 06:00 - 14:00
[2023-02-02] => REST DAY
[2023-02-03] => 06:00 - 14:00
[2023-02-04] => 06:00 - 14:00
[2023-02-05] => 06:00 - 14:00
[2023-02-06] => REST DAY
[2023-02-07] => 06:00 - 14:00
[2023-02-08] => 06:00 - 14:00
[2023-02-09] => 06:00 - 14:00
[2023-02-10] => DAY OFF
[2023-02-11] => 06:00 - 14:00
[2023-02-12] => -
[2023-02-13] => -
[2023-02-14] => -
[2023-02-15] => -
)
I've been trying to use filter, but since the version is 5.3 its not applicable. I've also not been using PHP so I've been a hard time with the syntax. Note that this is a legacy system.

You can loop through the array of objects and use conditional statements to check the values of specific properties, and increment a counter variable each time the condition is met. Here's an example to count the number of "REST DAY" values for the property "2023-02-02":
$array = [
(object) [
'ID' => 12345,
'Name' => 'TEST 1',
'position' => 'POS 1',
'2023-02-01' => '22:00 - 06:00',
'2023-02-02' => 'REST DAY',
// ...
],
(object) [
'ID' => 67890,
'Name' => 'TEST 2',
'position' => 'POS 2',
'2023-02-01' => '06:00 - 14:00',
'2023-02-02' => 'REST DAY',
// ...
]
];
$counter = 0;
foreach ($array as $object) {
if ($object->{"2023-02-02"} === "REST DAY") {
$counter++;
}
}
echo $counter; // Outputs: 2

Related

Loop trough and modify JSON response

I am making API request to Google Sheets and I receive this response:
Array
(
[0] => Array
(
[Title] => Hours
[January] => 1
[February] => 2
[March] => 3
[April] => 4
[May] => 5
[June] => 6
[July] => 7
[August] => 8
)
[1] => Array
(
[Title] => Days
[January] => 3
[February] => 5
[March] => 1
[April] => 6
[May] => 3
[June] => 7
[July] => 4
[August] => 2
)
[2] => Array
(
[Title] => Weeks
[January] => 3
[February] => 5
[March] => 3
[April] => 4
[May] => 0
[June] => 0
[July] => 2
[August] => 6
[September] => 0
[October] => 0
[November] => 1
[December] => 0
)
)
How could I loop trough and modify this array to something like this so I can use it with HighCharts JS library?
series: [{
title: 'Hours',
data: [1, 2, 3, 4, 5, 6 .......]
}, {
title: 'Days',
data: [4, 6, 3, 6, ........]
}, {
title: 'Weeks',
data: [1, 9, 1, 3, ........]
}, {
....
}]
I tried this way:
if ($response->status) {
$rawData = json_decode(json_encode($response->data), true);
}
$series = [];
foreach ($rawData as $index => $rawDatum) {
if (!isset($rawDatum['Title'])) {
continue;
}
foreach ($rawDatum as $columnKey => $value) {
if ($columnKey == 'CvA') {
$series[$columnKey]['Title'][] = $value;
}
}
}
What I got as result:
Array
(
[Title] => Array
(
[title] => Array
(
[0] => Hours
[1] => Days
[2] => Weeks
)
)
)
Also is there a way to get all names of the months saved in $months array for example without doubles?
The following piece of code will create an array with title and the values for each respective subarray Hours, Days, Weeks.
We will also collect the union of the months in an array named $months.
$series = [];
$months = [];
foreach ($rawData as $subarray) {
$title = $subarray['Title'];
// Remove title key
unset($subarray['Title']);
$series[] = [
'title' => $title,
'data' => array_values($subarray),
];
// Union operator to keep unique months.
$months += array_keys($subarray);
}
echo '<pre>';
print_r($months);
echo '</pre>';
echo '<pre>';
print_r($result);
echo '</pre>';
Result $months:
Array
(
[0] => January
[1] => February
[2] => March
[3] => April
[4] => May
[5] => June
[6] => July
[7] => August
[8] => September
[9] => October
[10] => November
[11] => December
)
Result $series:
Array
(
[0] => Array
(
[title] => Hours
[data] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
)
)
[1] => Array
(
[title] => Days
[data] => Array
(
[0] => 3
[1] => 5
[2] => 1
[3] => 6
[4] => 3
[5] => 7
[6] => 4
[7] => 2
)
)
[2] => Array
(
[title] => Weeks
[data] => Array
(
[0] => 3
[1] => 5
[2] => 3
[3] => 4
[4] => 0
[5] => 0
[6] => 2
[7] => 6
[8] => 0
[9] => 0
[10] => 1
[11] => 0
)
)
)
Given this data:
$data = [
[
'Title' => 'Hours',
'January' => 1,
'February' => 2,
'March' => 3,
'April' => 4,
'May' => 5,
'June' => 6,
'July' => 7,
'August' => 8,
],
[
'Title' => 'Days',
'January' => 3,
'February' => 5,
'March' => 1,
'April' => 6,
'May' => 3,
'June' => 7,
'July' => 4,
'August' => 2,
],
[
'Title' => 'Weeks',
'January' => 3,
'February' => 5,
'March' => 3,
'April' => 4,
'May' => 0,
'June' => 0,
'July' => 2,
'August' => 6,
'September' => 0,
'October' => 0,
'November' => 1,
'December' => 0,
]
];
You should be able to do this:
// Store everything here
$result = [];
foreach ($data as $item) {
// Grab the title
$ret['title'] = $item['Title'];
// Remove it from the source dataset
unset($item['Title']);
// Take the remaining values, join with comma
$ret['data'] = implode(',', array_values($item));
// Append to main array
$result[] = $ret;
}
You can skip the implode if want an actual array

How to get total hours from start time and end time with multi dimensional array along with over lapping check?

I have a below scenario where I need to check for the overlapping with-in a specific date array only and get total attended hours.
array (
'2020-07-14' =>
array (
'total_attended_hours' => 0,
0 =>
array (
'start_time' => '09:00:00',
'end_time' => '13:00:00',
'hours' => '4 hours 0 mins',
),
1 =>
array (
'start_time' => '13:30:00',
'end_time' => '16:30:00',
'hours' => '3 hours 0 mins',
),
2 =>
array (
'start_time' => '09:00:00',
'end_time' => '14:00:00',
'hours' => '5 hours 0 mins',
),
),
'2020-07-15' =>
array (
'total_attended_hours' => 0,
0 =>
array (
'start_time' => '13:30:00',
'end_time' => '17:00:00',
'hours' => '3 hours 30 mins',
),
1 =>
array (
'start_time' => '09:00:00',
'end_time' => '14:00:00',
'hours' => '5 hours 0 mins',
),
),
)
As in the above example with date 2020-07-14 we have start_time and end_time:- total_attended_hoursshould be equals to7 hours 30 mins``
And for next 2020-07-15 it should be total_attended_hours = 8 hours 0 mins
Playground
New issue with below array
$data = [
'2020-07-14' =>
[
[
'start_time' => '14:15:00',
'end_time' => '17:45:00',
],[
'start_time' => '14:30:00',
'end_time' => '17:30:00',
],[
'start_time' => '14:30:00',
'end_time' => '17:30:00',
],
],
'2020-07-15' => [
[
'start_time' => '13:30:00',
'end_time' => '17:00:00',
],[
'start_time' => '09:00:00',
'end_time' => '14:00:00',
],
],
];
Result :-
Array
(
[2020-07-14] => Array
(
[0] => Array
(
[start_time] => 14:15:00
[end_time] => 17:45:00
)
[1] => Array
(
[start_time] => 14:30:00
[end_time] => 17:30:00
)
[2] => Array
(
[start_time] => 14:30:00
[end_time] => 17:30:00
)
[total_attended_hours] => 03:15:00
)
Where as [total_attended_hours] => 03:15:00 should be [total_attended_hours] => 03:30:00
Here you got the algorythm:
For each set of Time-Bookings do the following
Find the smallest start_time
Add the duration between start_time and end_time to a sum
Find the next smallest Time-Booking by start_time
IF current_end_time < previous_end_time jump to 4 END IF
IF start_time < previous_end_time subtract difference from sum END IF
Add duration between start_time and end_time
Jump to 4 until there is no matching element left.
Happy coding :)
EDIT - add more clean implementation
function getSortedDays(array $days): array {
return array_map(function (array $day) {
array_multisort(array_column($day, 'start_time'), SORT_ASC, $day);
return $day;
}, $days);
}
function addTotalAttendedHours(array $days): array {
$sortedDays = getSortedDays($days);
$days = array_map(function (array $day) {
$sum = (new DateTime())->setTimestamp(0);
$previousEnd = null;
foreach ($day as $time) {
$currentStart = new DateTimeImmutable($time['start_time']);
$currentEnd = new DateTimeImmutable($time['end_time']);
if ($currentEnd < $previousEnd) continue; // this has been added
$sum->add($currentStart->diff($currentEnd));
if ($previousEnd !== null && $currentStart < $previousEnd) {
$sum->sub($currentStart->diff($previousEnd));
}
$previousEnd = $currentEnd;
}
$attendedSeconds = $sum->getTimestamp();
$day['total_attended_hours'] = sprintf(
'%02u:%02u:%02u',
$attendedSeconds / 60 / 60,
($attendedSeconds / 60) % 60,
$attendedSeconds % 60
);
return $day;
}, $sortedDays);
return $days;
}
Working example.

PHP Forming Custom Array from Array within array

I'm having an array of three months which has Three Months Data and it holds Savings & Discount Information something like the below:
graphData holds the DataArr.
[DataArr] => Array
[0] => Array
(
[data] => Array
(
[0] => Array
(
[Month] => 10 Jan 2019
[Cost] => 60.3
[Name] => Savings
)
[1] => Array
(
[Month] => 10 Feb 2019
[Cost] => 45.3
[Name] => Savings
)
[2] => Array
(
[Month] => 10 Mar 2019
[Cost] => 50.6
[Name] => Savings
)
)
)
[1] => Array
(
[data] => Array
(
[0] => Array
(
[Month] => 10 Jan 2019
[Cost] => 89.62
[Name] => Discount
)
[1] => Array
(
[Month] => 10 Feb 2019
[Cost] => 20.2
[Name] => Discount
)
[2] => Array
(
[Month] => 10 Mar 2019
[Cost] => 0.0
[Name] => Discount
)
)
)
REQUIRED ARRAY - To Pass into Morris.js Line Chart
Now I want to iterate into this array and want to have the array format in a way as below
[data] => Array
(
[0] => Array
(
[Month] => 10 Jan 2019
[Savings] => 60.3
[Discount] => 89.62
)
[1] => Array
(
[Month] => 10 Feb 2019
[Saving] => 45.3
[Discount] => 20.2
)
[2] => Array
(
[Month] => 10 Mar 2019
[Saving] => 50.6
[Discount] => 0.0
)
)
Can you please share me how I can go about getting this into the required array using PHP? I tried array_push and other methods with JQuery Array methods as well, but all my efforts failed, and I'm working on this from past 3 days, any help is greatly appreciated.
Even tried with PHP foreach but even that failed, missing something and have no more ideas on how to get this working! Please let me know if any of you have much ideas on this.
Thanks
EDIT
**SAMPLE CODE I TRIED IN PHP **
for($k = 0; $k < sizeof($graphData['DataArr']); $k++ ) {
for($l = 0; $l < sizeof($graphData['DataArr'][$k]); $l++ ) {
array_push($graphData['DataArr'], array(
'label' => $graphData['DataArr'][$k][$l]['label'],
'percent' => $graphData['DataArr'][$k][$l]['percentage']
)
);
}
}
Here label => COST, DISCOUNT and Percentage is the value associated with the labels.
<?php
$graphData =
array(
'DataArr' =>
array
(
array(
'data' => array
(
array
(
'Month' => '10 Jan 2019',
'Cost' => 60.3,
'Name' => 'Savings'
),
array
(
'Month' => '10 Feb 2019',
'Cost' => 45.3,
'Name' => 'Savings'
),
array
(
'Month' => '10 Mar 2019',
'Cost' => 50.6,
'Name' => 'Savings'
)
)
),
array
(
'data' => array
(
array
(
'Month' => '10 Jan 2019',
'Cost' => 89.62,
'Name' => 'Discount'
),
array
(
'Month' => '10 Feb 2019',
'Cost' => 20.2,
'Name' => 'Discount'
),
array
(
'Month' => '10 Mar 2019',
'Cost' => 0.0,
'Name' => 'Discount'
)
)
)
)
);
$result = [];
foreach($graphData['DataArr'] as $value){
foreach($value['data'] as $details){
if(!isset($result['data'][$details['Month']])) $result['data'][$details['Month']] = ['Month' => $details['Month']];
$result['data'][$details['Month']][$details['Name']] = $details['Cost'];
}
}
$result['data'] = array_values($result['data']); // to eliminate keys
print_r($result);
Demo: https://3v4l.org/QMVuR
We first create a $result array with data key in it.
We loop over $graphData and store the values of Month,Savings and Discount under the indexed key value of Month.
In the end, we do array_values() to remove the keys.
Based on what you provided here is the code need to produce the new Array:
<?php
$data = [
[
'data' => [
[
'Month' => '10 Jan 2019',
'Cost' => 60.3,
'Name' => 'Savings'
],
[
'Month' => '10 Feb 2019',
'Cost' => 45.3,
'Name' => 'Savings'
],
[
'Month' => '10 Mar 2019',
'Cost' => 50.6,
'Name' => 'Savings'
]
],
],
[
'data' => [
[
'Month' => '10 Jan 2019',
'Cost' => 89.62,
'Name' => 'Discount'
],
[
'Month' => '10 Feb 2019',
'Cost' => 20.2,
'Name' => 'Discount'
],
[
'Month' => '10 Mar 2019',
'Cost' => 0.0,
'Name' => 'Discount'
]
],
]
];
$new_arr = ['data' => []];
echo "<pre>";
foreach( $data[0]['data'] as $key => $value) {
// $new_arr['data'][$k]['Month'] =
$new_arr['data'][$key]['Month'] = $value['Month'];
$new_arr['data'][$key]['Discount'] = $value['Cost'];
$new_arr['data'][$key]['Savings'] = $data[1]['data'][$key]['Cost'];
}
print_r($new_arr);
Note: this code assumes that $data array will only have 2 main elements, more elements in this array might might cause different behaviour.

Adding multi dimensional array to database in PHP

Array ( [0] => Array ( [0] => Array ( [name] => Heart Choclates [code] => LFB-P-10 [qty] => 1 [type] => main [price] => 1200 [stock] => 5 [image] => choclates-valentines-day.jpg [quantity] => 12 [expdate] => May 27th 2017 [exptime] => 11:00 PM to 12:00 AM [expdtype] => Mid night delivery ) [1] => Array ( [name] => Birthday Pink [code] => KB-P-5 [qty] => 1 [type] => addon [price] => 600 [stock] => 7 [image] => pink-roses.jpg [expdate] => May 27th 2017 [exptime] => 11:00 PM to 12:00 AM [expdtype] => Mid night delivery ) ) [1] => Array ( [0] => Array ( [name] => Red & Yellow Roses [code] => KB-P-6 [qty] => 1 [type] => main [price] => 800 [stock] => 9 [image] => birthday-red-roses.jpg [expdate] => May 27th 2017 [exptime] => 11:00 PM to 12:00 AM [expdtype] => Mid night delivery ) [1] => Array ( [name] => Signature Cake [code] => KB-P-7 [qty] => 1 [type] => addon [price] => 0 [stock] => 9 [image] => signature-cake.jpg [expdate] => May 27th 2017 [exptime] => 11:00 PM to 12:00 AM [expdtype] => Mid night delivery ) [2] => Array ( [name] => Truffle Cake [code] => KB-P-8 [qty] => 1 [type] => addon [price] => 10 [stock] => 7 [image] => truffle-cake.jpg [expdate] => May 27th 2017 [exptime] => 11:00 PM to 12:00 AM [expdtype] => Mid night delivery ) ) )
I have an array like this.. an array of orders and array of products inside each array of orders. Now i need to add these arrays into database with orders in each row and products seprated by a <br/> . How is it possible? Thanks in advance.
I used this for each to print the code.
<?php
session_start();
error_reporting(0);
print_r($_SESSION["products"]);
foreach($_SESSION["products"] as $row => $temp){
?>
<div>
<?php
foreach($temp as $innerRow => $cart_itm){
?>
<div><?php echo $cart_itm['code']; ?></div>
<?php
}
?>
</div>
<?php
}
?>
Expecting this Result
Try this sample code.
$orderList[1001] = array(
0 => array(
'name' => 'Heart Choclates',
'code' => 'LFB-P-10',
'qty' => 1,
'type' => 'main',
'price' => 1200,
'stock' => 5,
'image' => 'choclates-valentines-day.jpg',
'quantity' => 12,
'expdate' => 'May 27th 2017',
'exptime' => '11:00 PM to 12:00 AM',
'expdtype' => 'Mid night delivery'
),
1 => array(
'name' => 'Birthday Pink',
'code' => 'KB-P-5',
'qty' => 1,
'type' => 'addon',
'price' => 600,
'stock' => 7,
'image' => 'pink-roses.jpg',
'quantity' => 3,
'expdate' => 'May 27th 2017',
'exptime' => '11:00 PM to 12:00 AM',
'expdtype' => 'Mid night delivery'
)
);
$orderList[1002] = array(
0 => array(
'name' => 'Red & Yellow Roses',
'code' => 'KB-P-6',
'qty' => 1,
'type' => 'main',
'price' => 800,
'stock' => 9,
'image' => 'birthday-red-roses.jpg',
'quantity' => 10,
'expdate' => 'May 27th 2017',
'exptime' => '11:00 PM to 12:00 AM',
'expdtype' => 'Mid night delivery'
)
);
echo '<pre>';
print_r($orderList);
echo '<pre>';
$productList = array();
foreach ($orderList as $key => $value)
{
$names = array();
$quantity = array();
foreach ($value as $key1 => $value1)
{
$names[] = $value1['name'];
$quantity[] = $value1['quantity'];
}
$productList[$key]['names'] = implode('<br>', $names); // Used `:` insted of '<br>' for separator. But, You can use whatever you want. But, better don't use any HTML tag.
$productList[$key]['quantity'] = implode('<br>', $quantity);
}
echo '<pre>';
print_r($productList);
echo '<pre>';
// Sample DATA INSERTION Query by PDO
try {
$conn = new PDO('mysql:host=localhost;dbproductName=someDatabase', $userproductName, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Prepare the query ONCE
$stmt = $conn->prepare('INSERT INTO someTable VALUES(:name, :quantity)');
foreach ($productList as $key => $value) {
$productName = $value['names'];
$productQuantity = $value['quantity'];
$stmt->bindParam(':name', $productName);
$stmt->bindParam(':quantity', $productQuantity);
$stmt->execute();
}
} catch(PDOException $e) {
echo $e->getMessage();
}
// Ref : https://code.tutsplus.com/tutorials/php-database-access-are-you-doing-it-correctly--net-25338
I hope this will get you started:
$data = array(
array(
array(
'name' => 'Heart Choclates',
'code' => 'LFB-P-10',
'qty' => '1'
),
array(
'name' => 'Birthday Pink',
'code' => 'KB-P-5',
'qty' => '1'
)
),
array(
array(
'name' => 'Red & Yellow Roses',
'code' => 'KB-P-6',
'qty' => '1'
),
array(
'name' => 'Signature Cake',
'code' => 'KB-P-7',
'qty' => '1'
),
array(
'name' => 'Truffle Cake',
'code' => 'KB-P-8',
'qty' => '1'
)
)
);
foreach( $data as $row_item )
{
$row = array();
foreach( $row_item as $product )
{
foreach( $product as $key => $value )
{
if( isset( $row[ $key ] ) )
$row[ $key ] .= $value . ' <br> ';
else
$row[ $key ] = $value . ' <br> ';
}
}
//---
echo 'Row: <br>';
var_dump( $row );
echo '<br><br>';
//-- insert the contents of $row array into the database
}
Output:
You can insert the contents of $row array into database.
EDIT
Please note that, the above answer is based on your specific question that you asked.
I still didn't understood what exactly you are doing here. If you are trying to store the details of an order, then this is a poor method of accomplishing it! You should keep separate database table and use a relationship to join together. This is what a relational database is for!
For example, let the two tables be tblOrderMaster and tblOrderDetails.
Here, in the tblOrderMaster table, the primary key will be the order_id and you would probably gonna store the total amount, discount amount, total service tax, order date, customer id, order status, etc.
And in the tblOrderDetails table, you are gonna have several rows, in which we are gonna store each products of a particular order. For example, it will store order id (foreign key), product id, unit price, quantity, tax, total (unit_price x quantity), etc..
This would be the proper way, I believe.

Duplicate php array with keys

I have two arrays like so:
[day0_units] => 0
[day1_units] => 12
[day1_start] => 08:00:00
[day1_end] => 11:00:00
[day2_units] => 12
[day2_start] => 07:00:00
[day2_end] => 11:00:00
[day3_units] => 0
[day4_units] => 12
[day4_start] => 10:00:00
[day4_end] => 12:00:00
[day5_units] => 12
[day5_start] => 08:00:00
[day5_end] => 03:00:00
[day6_units] => 0
[day0_units] => 0
[day0_start] => 10:00:00
[day0_end] => 01:00:00
[day1_units] => 12
[day1_start] => 08:00:00
[day1_end] => 11:00:00
[day2_units] => 12
[day2_start] => 07:00:00
[day2_end] => 11:00:00
[day3_units] => 0
[day3_start] =>
[day3_end] =>
[day4_units] => 12
[day4_start] => 10:00:00
[day4_end] => 12:00:00
[day5_units] => 12
[day5_start] => 08:00:00
[day5_end] => 03:00:00
[day6_units] => 0
All I want to do is duplicate the array keys, both arrays should have the same keys in the same positions and retain the values if any. Any suggestions?
Get the keys from both and merge them, then flip and merge with the arrays:
$keys = array_flip(array_merge(array_keys($array1), array_keys($array2)));
$array1 = array_merge($keys, $array1);
$array2 = array_merge($keys, $array2);

Categories