PHP Custom Sort Multi-Dimensional Array by DateTime Field - php

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

Related

How to check array object and array?

First array:
[VariationSpecificsSet] => SimpleXMLElement Object
(
[NameValueList] => Array
(
[0] => SimpleXMLElement Object
(
[Name] => Size
[Value] => Array
(
[0] => 5FT King Size
[1] => 4FT6 Double
)
)
[1] => SimpleXMLElement Object
(
[Name] => Main Colour
[Value] => Array
(
[0] => Brown
[1] => Black
)
)
)
)
Second Array:
[Variation] => SimpleXMLElement Object
(
[StartPrice] => 14.99
[Quantity] => 12
[VariationSpecifics] => SimpleXMLElement Object
(
[NameValueList] => SimpleXMLElement Object
(
[Name] => Size
[Value] => No.10-1M
)
)
)
examine above two arrays
i want to store value NameValueList in database but the problem is sometimes it is SimpleXMLElement Object and sometimes it is Array
how can i store them ...??
You can detect is by is_array().
$myVal=$test['NameValueList'];
if(is_array($myVal) && count($myVal)>0){
foreach($myVal as $item){
echo $item->Name.":".echo $item->Value;
}
} else {
echo $myVal->Name.":".echo $myVal->Value;
}
Did you tried using json_encode like below.
You can convert the object to array.
$array=json_decode(json_encode($object),true);

php array multisort by inner arrays value [duplicate]

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 7 years ago.
I am trying to sort vote-list in PHP.
The list is an array, containing class-objects:
Array
(
[0] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => bbh - bghs dsdw
)
[votes] => SimpleXMLElement Object
(
[0] => 6
)
[key] => SimpleXMLElement Object
(
[0] => bbh--0
)
)
[1] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => aaa - bbb
)
[votes] => SimpleXMLElement Object
(
[0] => 4
)
[key] => SimpleXMLElement Object
(
[0] => aaa--0
)
)
[2] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => wdewv - qwdqs
)
[votes] => SimpleXMLElement Object
(
[0] => 3
)
[key] => SimpleXMLElement Object
(
[0] => wdewv--0
)
)
[3] => VotedSong Object
(
[title] => SimpleXMLElement Object
(
[0] => Hsg and fdSv - aGamaama
)
[votes] => SimpleXMLElement Object
(
[0] => 2
)
[key] => SimpleXMLElement Object
(
[0] => hsgandfdsv--0
)
)
)
I managed to sort there by the ->key wich is working fine:
usort($votedsongs, function ($a, $b) { return $b->votes - $a->votes; });
But after this, I still need another sort-function to sort those songs that have the same amout of votes by ->title.
I already found some solutions that deal with problems alike, but those did not work for me.
Any ideas on this?
Sounds like you are wanting to sort the VotedSong objects in the array by votes and then by title (which is misspelled as titel). If so, this could work:
usort($votedsongs, function ($a, $b) {
if ($b->votes == $a->votes) {
return ($a->title < $b->title) ? -1 : 1;
}
return $b->votes - $a->votes;
});
Thanks to splash58 for this solution:
if (!($r = $b->votes - $a->votes)) $r = strcmp($b->title, $a->title); return $r;
I modified the alphabetic sort to be non-casesensitive and switched $a->title and $b->title - that's it:
usort($votedsongs, function ($a, $b) {
if (!($r = $b->votes - $a->votes)) $r = strcasecmp($b->title, $a->title); return $r;
});

Duplicate php object into two similar objects

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;.

combine 2 associative arrays where values match

I have 2 associative arrays: $arr1 & $arr2. I'd like to create $arr3, which would combine 'name' and 'character' if the dates match...if the dates don't match, then just the character:
Here's $arr1:
Array
(
[0] => stdClass Object
(
[date] => 2010/01/01
[name] => Mario Lopez
)
[1] => stdClass Object
(
[date] => 2010/01/02
[name] => Lark Voorhies
)
)
Here's $arr2:
Array
(
[0] => Array
(
[date] => 2010/01/01
[character] => AC Slater
)
[1] => Array
(
[date] => 2010/01/02
[character] => Lisa Turtle
)
[2] => Array
(
[date] => 2010/01/03
[character] => Kelly Kapowski
)
)
Using array_intersect gives the following error: "Object of class stdClass could not be converted to string".
Here's what I'd like to get, if it's possible (ie $arr3):
Array
(
[0] => stdClass Object
(
[date] => 2010/01/01
[name] => Mario Lopez
[character] => AC Slater
)
[1] => stdClass Object
(
[date] => 2010/01/02
[name] => Lark Voorhies
[character] => Lisa Turtle
)
[2] => stdClass Object
(
[date] => 2010/01/03
[character] => Kelly Kapowski
)
)
This function was posted on php.net and I've been using it for quite a while. It should do what you are asking for
function array_extend($a, $b) {
foreach($b as $k=>$v) {
if( is_array($v) ) {
if( !isset($a[$k]) OR isset($v[0])) {
$a[$k] = $v;
} else {
$a[$k] = array_extend($a[$k], $v);
}
} else {
$a[$k] = $v;
}
}
return $a;
}
Usage:
$array = array_extend($orig_array,$new_array);
Note that you will either have to convert your objects to arrays or modify the function to convert the object to an array on the fly ($a = (array) $a);
Edit:
Original source http://www.php.net/manual/en/function.array-merge.php#95294
Note that I made a small modification to resolve an issue with the given function where it would not properly extend an array with numeric keys

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