Duplicate php object into two similar objects - php

I have an object with some variables for events (id, date, time, etc) gathered from a database. Some events have multiple days per week, so I want to duplicate the event object for each day listed and mark which day it's being duplicated for.
For example, I have this object inside an array:
Array
(
[0] => stdClass Object
(
[id] => 1
[days] => Array
(
[0] => Mon
[1] => Tues
)
)
)
and I'd like it to look like this:
Array
(
[0] => stdClass Object
(
[id] => 1
[day] => Mon
[days] => Array
(
[0] => Mon
[1] => Tues
)
)
[1] => stdClass Object
(
[id] => 1
[day] => Tues
[days] => Array
(
[0] => Mon
[1] => Tues
)
)
)
For some reason, when it loops through the second time the object is getting updated in the 0 position of the main array and the 1 position like so:
Array
(
[0] => stdClass Object
(
[id] => 1
[day] => Tues
[days] => Array
(
[0] => Mon
[1] => Tues
)
)
[1] => stdClass Object
(
[id] => 1
[day] => Tues
[days] => Array
(
[0] => Mon
[1] => Tues
)
)
)
This is a replication of the array declaration and loop I'm using:
$out = array();
$arr = array();
$arr[0] = new stdClass();
$arr[0]->id = 1;
$arr[0]->days = array("Mon","Tues");
foreach($arr as $a){
foreach($a->days as $day){
$a->day = $day;
$out[] = $a;
}
}
I did the same thing with straight arrays (cast the object as an array) and there it worked as I hoped, but it'd be nice to know how to do it with objects as well.
Any ideas?

You've got a single object, $a, referenced from both spots in the array. To duplicate the object instead use $out[] = clone $a; in place of $out[] = $a;.

Related

PHP check if array value occurs in all multidimensional arrays

I have the following multi dimensional PHP array. What I'm trying to do is return only the value which occurs in all of the arrays.
So in the array below the only value which occurs in every array is "2018-02-22", so I want to create a new array with only this value.
I feel like it can't be too difficult, but I just can't get my head around how to do this. If any one can help it would be much appreciated!
Array
(
[0] => Array
(
[0] => 2018-02-22
)
[1] => Array
(
[0] => 2018-02-22
[1] => 2018-02-21
[2] => 2018-02-20
[3] => 2018-02-16
[4] => 2018-02-14
)
[2] => Array
(
[0] => 2018-02-20
[1] => 2018-02-19
[2] => 2018-02-21
[3] => 2018-02-22
[4] => 2018-02-14
)
[3] => Array
(
[0] => 2018-02-22
[1] => 2018-02-12
[2] => 2018-02-01
)
)
So to clarify the output I'm aiming for is:
Array
(
[0] => 2018-02-22
)
You can do it by array_intersect, to get common value 2018-02-22.
<?php
$dates = [
["2018-02-22","2018-02-23"],
["2018-02-22","2018-02-24"],
["2018-02-22","2018-02-25"],
];
$common = array_shift($dates);
foreach($dates as $key=>$date){
$common = array_intersect($common, $date);
}
print_r($common);
?>
Live Demo
Output is :
Array (
[0] => 2018-02-22
)

PHP Sum multi-dimentional array date interval, for an employee clock

time is DateTime Object formatted as:
$time = $date->format("%H:%i:%s");
I'm trying to sum hours and group employees.
I have:
Array
(
[0] => Array
(
[employee] => 2
[time] => 00:0:17
)
[1] => Array
(
[employee] => 1
[time] => 00:0:4
)
[2] => Array
(
[employee] => 2
[time] => 02:0:0
)
[3] => Array
(
[employee] => 3
[time] => 02:0:0
)
[4] => Array
(
[employee] => 3
[time] => 01:0:0
)
)
And I need something like, grouped and sum:
Array
(
[0] => Array
(
[employee] => 2
[totalTime] => 02:0:17
)
[1] => Array
(
[employee] => 1
[totalTime] => 00:0:4
)
[2] => Array
(
[employee] => 3
[totalTime] => 03:0:0
)
)
Any thoughts? Maybe convert time to UNIX and manipulate from there?
Since you want something like like the desired output, perhaps this will do:
foreach($array as $value){
if(!isset($data[$value['employee']])){
$data[$value['employee']] = 0;
}
$parsed = date_parse($value['time']);
$data[$value['employee']] += $parsed['hour'] * 3600 + $parsed['minute'] * 60 + $parsed['second'];
}
print_r($data);
Instead of creating a multidimensional array, $data will have the key of the employee and the value of the total time in seconds.
Obviously you can convert seconds very easily to a format if you so please.

PHP Custom Sort Multi-Dimensional Array by DateTime Field

I searched for this, and it seems the ones similar to this are all going to be "custom" based on the poster's original array structure.
I'm struggling with getting the array below sorted by the [DateTime] key of each entry. I'd like them sorted Ascending (newest datetime with the highest array index), and would like to retain the array structure and keys if possible.
Array
(
[0] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => RTU-12 Merchandise Support, Fan Status Switch
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm Recall
)
[Description] => SimpleXMLElement Object
(
[0] => No Flow
)
[DateTime] => 07-25-2015 20:09:47
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 2
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 7
)
)
[1] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => RTU-03 Checkout Area, Fan Status Switch
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm Recall
)
[Description] => SimpleXMLElement Object
(
[0] => No Flow
)
[DateTime] => 07-25-2015 20:09:44
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 2
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 7
)
)
... SOME INDICES REMOVED FOR READABILITY ...
[12] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => ~RackA\SGr2\Cmp4, Proof of Running
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm Recall
)
[Description] => SimpleXMLElement Object
(
[0] => No Proof
)
[DateTime] => 07-25-2015 19:39:13
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 1
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 2
)
)
[13] => Array
(
[Source] => SimpleXMLElement Object
(
[0] => ~RackC\SGr1, Suction Pressure
)
[EventType] => SimpleXMLElement Object
(
[0] => Alarm
)
[Description] => SimpleXMLElement Object
(
[0] => Pressure too high
)
[DateTime] => 07-25-2015 19:14:21
[Priority] => SimpleXMLElement Object
(
[0] => Medium
)
[SubSystemKey] => SimpleXMLElement Object
(
[0] => 1
)
[ViewKey] => SimpleXMLElement Object
(
[0] => 4
)
)
[Count] => 14
[NewEvents] => 14
[Result] => Success
)
Here is what I've tried so far:
function date_compare($a, $b)
{
$t1 = strtotime($a['DateTime']);
$t2 = strtotime($b['DateTime']);
return $t1 > $t2;
}
usort($alarms, 'date_compare');
My results are simply an unsorted (and seemingly broken organization) array. I'm not too skilled with usort's, so looking for some guidance.
Thanks!
It seems strtotime() doesn't parse this date format: 07-25-2015 19:39:13, which is confirmed by some quick experimentation:
var_dump(strtotime("07-25-2015 19:39:13"));
bool(false)
var_dump(strtotime("07/25/2015 19:39:13"));
int(1437845953)
A detailed list of date formats usable by strtotime() is available here:
http://php.net/manual/en/datetime.formats.date.php
The quickest way to solve this is to convert the dashes into slashes:
function date_compare($a, $b) {
$t1 = strtotime(str_replace('-', '/', $a['DateTime']));
$t2 = strtotime(str_replace('-', '/', $b['DateTime']));
return $t1 > $t2;
}
usort($alarms, 'date_compare');
You might want to use uasort() to preserve the keys of your array.
http://php.net/manual/en/function.uasort.php
Also consider this:
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
http://php.net/manual/en/function.usort.php
Therefore:
function date_compare($a, $b) {
$t1 = strtotime(str_replace('-', '/', $a['DateTime']));
$t2 = strtotime(str_replace('-', '/', $b['DateTime']));
return $t1 > $t2 ? -1 : 1;
}
uasort($alarms, 'date_compare');
You could also use array_multisort with a "NATURAL" flag.
$dateTime = array();
foreach ($array as $tempArray) {
$dateTime[] = $tempArray["DateTime"];
}
array_multisort($dateTime, SORT_NATURAL, $array);
Got some help from
http://shiflett.org/blog/2011/jun/sorting-multi-dimensional-arrays-in-php

Rename multidimensional array keys

I'm trying to rename my keys in a multidimensional array. I looked at this: Renaming the keys in multidimensional associate arrays and it does rename it, but only for 1 of my 2 arrays. How can I get it to rename the 1st array time and the second array count?
My output right now is :
Array
(
[0] => Array
(
[0] => 00:00
[1] => 00:15
[2] => 00:30
)
[1] => Array
(
[0] => 8
[1] => 9
[2] => 8
)
)
I need [0] to be time and [1] to be count.
If I use this:
foreach ($sliced_array as $id => $dataset) {
$newArray["time"] = $dataset;
}
I can get it to output only array [1] renamed as time. It should be count and array [0] disappears entirely. Is there a way to focus which dataset the foreach targets? dataset[0] does not work.
My expected output is:
Array
(
[time] => Array
(
[0] => 00:00
[1] => 00:15
[2] => 00:30
)
[count] => Array
(
[0] => 8
[1] => 9
[2] => 8
)
)
Did you just try:
$myArray["time"] = $myArray[0];
$myArray["count"] = $myArray[1];
unset($myArray[0]);
unset($myArray[1]);
or just:
$newArray["time"] = $myArray[0];
$newArray["count"] = $myArray[1];
?
$newArray = array_combine(array('time','count'),$sliced_array);
http://es1.php.net/array_combine

How to sort a PHP by date

Here is my array:
Array (
[0] => Array ( [0] => content here [1] => 2010-02-04 01:25:34 )
[1] => Array ( [0] => content here [1] => 2010-02-04 04:51:37 )
[2] => Array ( [0] => content here [1] => 2010-02-04 04:52:31 )
[3] => Array ( [0] => content here [1] => 2010-02-04 05:50:48 )
[4] => Array ( [0] => content here [1] => 2010-02-04 03:25:34 )
[5] => Array ( [0] => content here [1] => 2010-02-04 05:39:33 )
[6] => Array ( [0] => content here [1] => 2010-02-04 03:25:34 )
[7] => Array ( [0] => content here [1] => 2010-02-04 07:07:09 )
[8] => Array ( [0] => content here [1] => 2010-02-04 07:07:23 )
[9] => Array ( [0] => content here [1] => 2010-02-04 08:51:18 )
)
How can I sort it by the timestamp?
Or usort() with strtotime():
function compare($e1, $e2) {
$t1 = strtotime($e1[1]));
$t2 = strtotime($e2[1]));
if($t1 == t2) {
return 0;
}
return ($t1 > $t2) ? 1 : -1;
}
usort($array, 'compare');
Use usort() with a cmp_function that compares index 1 of each of the passed arguments.
Use array_multisort.
array_multisort() It's a nasty but powerful little function. Basically you'll have to iterate through your array, pulling out the date stamp into a new array - maintaining key association. Then, sort that new array, still maintaining key association. Then throw both your newly sorted array and the original array into array_multisort() and your original array will be sorted to have keys in the same order as your sorted array.
Clear as mud? The examples on that doc page should help.
How about Bubble sort?
That means looping through each date, check if the previous is bigger, etc.

Categories