Sort Multiarray in php [duplicate] - php

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 2 months ago.
I need some help about sorting a multiple array.
This is what I got:
Array (
[ALU0000001] =>
Array ( [0] => Array ( [period] => 2012 [codCurse] => S12-2030 [idPersona] => ALU0000001 [date] => 2012-04-02 [amount] => 238.00 [active] => X )
[1] => Array ( [period] => 2012 [codCurse] => S12-2030 [idPersona] => ALU0000001 [date] => 2012-05-02 [amount] => 238.00 [active] => X )
[2] => Array ( [period] => 2012 [codCurso] => S12-2030 [idPersona] => ALU0000001 [date] => 2012-06-02 [amount] => 238.00 [active] => X )
[3] => Array ( [period] => 2013 [codCurso] => S12-2030 [idPersona] => ALU0000001 [date] => 2013-01-02 [amount] => 238.00 [active] => X )
[ALU0000005] =>
Array ( [0] => Array ( [period] => 2013 [codCurse] => S13-2010 [idPersona] => ALU0000005 [date] => 2013-03-01 [amount] => 225.00 [active] => X )
[1] => Array ( [period] => 2013 [codCurse] => S13-2010 [idPersona] => ALU0000005 [date] => 2013-03-02 [amount] => 333.00 [active] => X )
[2] => Array ( [period] => 2013 [codCurse] => S13-2010 [idPersona] => ALU0000005 [date] => 2013-04-02 [amount] => 333.00 [active] => X )
I need to sort multiarray by period date to get something like this
Y M D
2012 2012-04-02 ALU00000001 .....
2012 2012-05-02 ALU00000005 .....
2012 2012-06-01 ALU00000001 .....
2013 2013-01-01 ALU00000001 .....
2013 2013-06-01 ALU00000001 .....
2013 2013-12-24 ALU00000005 .....
Thanks

As danp says you will need a custom sort function using PHP usort.
You execute this in Codeigniter using the syntax;
usort($data_array, array('controller', 'sort_function'));
function sort_function($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}

Considering the main array keys don't do much (because they're already contained within the values by the date key) you can safely ignore them. So first you want to collect all the values into a single array to be able to sort later:
$allItems = array();
foreach ($outputArr as $arr) { // $outputArr should be the name of your array
$allItems = array_merge($allItems,array_values($arr));
}
Then you need to sort the array values by the date keys:
function sortByDate($a,$b) {
$d1 = strtotime($a['date']);
$d2 = strtotime($b['date']);
return $d1 == $d2 ? 0 : ($d1 > $d2 ? 1 : -1);
}
usort($allItems,'sortByDate');
// and there you go.
print_r($allItems);

Related

PDO select and show data array with same date

I've made this code. To show the data based on same date (day)
$group = array();
$stmt = $conn->prepare("
SELECT *,date(date_added) as dateadded
FROM rr
ORDER BY dateadded DESC
");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($res = $stmt->fetch()){
$rtype = array();
$rtype['type'] = "date";
$rtype['date'] = date_format (new DateTime($res['dateadded']), 'M jS, Y');
$rtype[] = $res;
$result[] = $rtype;
}
What I got as result from query sql
array
(
[0] => Array
(
[type] => date
[date] => Dec 18th, 2019
[0] => Array
(
[id] => 1
[user_id] => 1
[status] => 1
[date_added] => 2019-12-18 13:44:30
[dateadded] => 2019-12-18
)
)
[1] => Array
(
[type] => date
[date] => Dec 20th, 2019
[0] => Array
(
[id] => 3
[user_id] => 2
[status] => 2
[date_added] => 2019-12-20 14:53:04
[dateadded] => 2019-12-20
)
)
[2] => Array
(
[type] => date
[date] => Dec 29th, 2019
[0] => Array
(
[id] => 5
[user_id] => 3
[status] => 0
[date_added] => 2019-12-29 00:39:21
[dateadded] => 2019-12-29
)
)
)
There is some data that is not show as result in the same date.
What I want to show is like this.
Array
(
[0] => Array
(
[type] => date
[date] => Dec 18th, 2019
)
[1] => Array
(
[id] => 2
[user_id] => 1
[status] => 1
[date_added] => 2019-12-18 13:44:30
)
[2] => Array
(
[type] => date
[date] => Dec 20th, 2019
)
[3] => Array
(
[id] => 1
[user_id] => 1
[status] => 0
[date_added] => 2019-12-20 14:53:04
)
[4] => Array
(
[id] => 3
[user_id] => 1
[status] => 0
[date_added] => 2019-12-20 14:53:04
)
)
The result is become an array like that with group by date (day).
How to get this result?
Thanks for helping me.
You need to set $group_date to the value of $res['dateadded'] so you can tell when the date changes. There's no need to use substr(), since dateadded just contains the date without a time.
You should push $res onto $result, not $rtype.
$group_date = "";
$group = array();
$stmt = $conn->prepare("
SELECT *,date(date_added) as dateadded
FROM rr
ORDER BY dateadded
");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($res = $stmt->fetch()){
$rtype = array();
if ($group_date !== $res["dateadded"]) {
$rtype['type'] = "date";
$rtype['date'] = date_format (new DateTime($res['dateadded']), 'M jS, Y');
$result[] = $rtype;
$group_date = $res["dateadded"];
}
$result[] = $res;
}

Check if multiple datetime are same in php foreach

I want to split items which have same date and different date.
foreach ($cart->getAllItems() as $item)
{
$pickupDateTime = $item->getCartPickupDate().' '.$itemgetCartPickupTime();
$pickupDateTime = date('Y-m-d G:i:s', strtotime($pickupDateTime)) //2018-03-09 6:03:00 or 2018-03-09 21:10:00
// Split items here with same Date //
if(Dates are Same Condition){
$items_normal[]= $item->getProductId();
}else
{
//If Dates Are diffrent
$ites_special[]= $item->getProductId();
}
}
Need to compare if dates are same in first if condition and in else part the items which have different dates.
Look at the following arrays, in this I have same date and time, I need to club those which have same date and time. In below example, the 3rd one must be come under first Array as it has different time i.e. 6:05 instead of 6:03
Array
(
[1] => Array
(
[product_id] => 742
[qty] => 1
[date] => 03/09/2018
[time] => 06:03 AM
[tax] => 0
[splinst] => null
)
[2] => Array
(
[product_id] => 743
[qty] => 1
[date] => 03/09/2018
[time] => 06:03 AM
[tax] => 0
[splinst] => null
)
)
Array
(
[3] => Array
(
[product_id] => 744
[qty] => 1
[date] => 03/09/2018
[time] => 06:03 AM
[tax] => 0.12
[splinst] => null
)
[4] => Array
(
[product_id] => 757
[qty] => 1
[date] => 03/09/2018
[time] => 06:05 AM
[tax] => 0.25
[splinst] => null
)
)
You should use the DateTime object:
$pickupDateTime = $item->getCartPickupDate().' '.$itemgetCartPickupTime();
$pickupDateTime = new DateTime($pickupDateTime);
You can compare two DateTime objects which each other:
if ($dateTimeObject1 == $dateTimeObject2) {
// both have same date and time
}
Be aware that you should not use strict comparison (===) here as it would check if it is the same object and not if the DateTime is the same.
If you need to compare only the date and ignore the time you can call setTime on both objects to reset the time to 0:
$dateTimeObject1->setTime(0, 0, 0);
$dateTimeObject2->setTime(0, 0, 0);
if ($dateTimeObject1 == $dateTimeObject2) {
// both have the same date
}
You could store the date in keys into an array to group items :
foreach ($cart->getAllItems() as $item)
{
$pickupDateTime = $item->getCartPickupDate().' '.$itemgetCartPickupTime();
$pickupDateTime = date('Y-m-d G:i:s', strtotime($pickupDateTime)) //2018-03-09 6:03:00 or 2018-03-09 21:10:00
$items_special[$pickupDateTime][] = $item->getProductId();
}
foreach ($items_special as $date => $items) {
if (count($items) > 1) {
$items_normal = $items ;
unset($items_special[$date]);
break;
}
}
$items_special = array_values($items_special);
So, $items_special will look like :
Array
(
[0] => Array
(
[product_id] => 757
[qty] => 1
[date] => 03/09/2018
[time] => 06:05 AM
[tax] => 0.25
[splinst] => null
)
)
And $items_normal will look like :
Array
(
[0] => Array
(
[product_id] => 742
[qty] => 1
[date] => 03/09/2018
[time] => 06:03 AM
[tax] => 0
[splinst] => null
)
[1] => Array
(
[product_id] => 743
[qty] => 1
[date] => 03/09/2018
[time] => 06:03 AM
[tax] => 0
[splinst] => null
)
[2] => Array
(
[product_id] => 744
[qty] => 1
[date] => 03/09/2018
[time] => 06:03 AM
[tax] => 0.12
[splinst] => null
)
)

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

Sort an Array of Objects within Array by value

Basically I'm trying to sort a complex array of Objects within an array:
Array
(
[190515] => stdClass Object
(
[nid] => 15740686
[venue_nid] => 190515
[occurrences] => 1
[this_weeks_occurrences] => 0
[end_date] => 1350853200
[end_date_end_time] => 1350853200
[is_ongoing] => 0
[title] => Wentz Concert Hall and Fine Arts Center
[times] => Array
(
[0] => stdClass Object
(
[nid] => 15740686
[venue_nid] => 190515
[venue_title] => Wentz Concert Hall and Fine Arts Center
[datepart] => 20121021
[occurrences] => 1
[times] => Sun 4:00pm
[end_times] => Sun 4:00pm
[next_year] => 0
[next_month] => 0
[next_week] => 3
[occurrence_date] => 1350853200
)
)
[times_list] => Array
(
[0] => Oct 21 sun 4:00pm
)
)
[31403] => stdClass Object
(
[nid] => 15740686
[venue_nid] => 31403
[occurrences] => 1
[this_weeks_occurrences] => 0
[end_date] => 1350176400
[end_date_end_time] => 1350176400
[is_ongoing] => 0
[title] => KAM Isaiah Israel
[times] => Array
(
[0] => stdClass Object
(
[nid] => 15740686
[venue_nid] => 31403
[venue_title] => KAM Isaiah Israel
[datepart] => 20121014
[occurrences] => 1
[times] => Sat 8:00pm
[end_times] => Sat 8:00pm
[next_year] => 0
[next_month] => 0
[next_week] => 2
[occurrence_date] => 1350176400
)
)
[times_list] => Array
(
[0] => Oct 13 sat 8:00pm
)
)
[33861] => stdClass Object
(
[nid] => 15740686
[venue_nid] => 33861
[occurrences] => 1
[this_weeks_occurrences] => 0
[end_date] => 1350781200
[end_date_end_time] => 1350781200
[is_ongoing] => 0
[title] => Music Institute of Chicago, Nichols Concert Hall
[times] => Array
(
[0] => stdClass Object
(
[nid] => 15740686
[venue_nid] => 33861
[venue_title] => Music Institute of Chicago, Nichols Concert Hall
[datepart] => 20121021
[occurrences] => 1
[times] => Sat 8:00pm
[end_times] => Sat 8:00pm
[next_year] => 0
[next_month] => 0
[next_week] => 3
[occurrence_date] => 1350781200
)
)
[times_list] => Array
(
[0] => Oct 20 sat 8:00pm
)
)
)
I need to sort by occurrence_date and ensure that the data in the top Object (e.g.190515) doesn't become corrupted with other objects and to include the possibility that there could be a 2nd occurrence_date for the "times" [array] of Objects.
I've seen similar sort arrays of objects by field here, but not with the depth of the array/object. I tried using usort but I don't think my syntax to the value is correct.
Basically what I tried.
function cmp($x, $y) {
if ($x->occurrence_date > $y->occurrence_date) {
return 1; }
else {
return -1; }
}
usort($node->timeout_events_schedule->venues, 'cmp');
Thanks in advance
How about:
function compare($x,$y)
{
if($x->times[0]->occurrence_date == $y->times[0]->occurrence_date)
return 0;
elseif($x->times[0]->occurrence_date < $y->times[0]->occurrence_date)
return -1;
else
return 1;
}
uasort($your_array,'compare');
uasort() preserve your keys, unlike usort()
http://www.php.net/manual/en/function.uasort.php
Few tips to help you solve your problem:
you will need uasort function, to preserve associative keys
You can not access occurrence_date key directly from $x o r $y, you will need $x->times[0]->occurence_date
Before doing comparison, iterate through $x->times just to check if there are more entries, pick one that suits your needs.
since occurence_date is a number you don't have to use string comparison function
Good luck :)

php merging arrays

In the multidimensional array below, I would like to merge arrays that have the same merge_id. I'm not sure "merge" is the right word: in the example below, array['0'] should become array['0'] with in it array['0']['0'] and array['0']['1'], the latter being equal to array['1']. I hope this makes sense ...
The array comes out of the db sorted on merge_id so arrays with matching merge_id are always "next to" each other, and there will only ever be 2 with the same merge_id
As I loop through the array I know I need to keep a variable that is always equal to the previous merge_id and if there is a match between previous and current, then merge.
Array
(
[0] => Array
(
[client_id] => 5
[company_name] => company111_name
[id] => 3
[fee] => 111
[year] => 2009
[quarter] => 3
[date_inserted] => 1264948583
[description] => 2009 - Q3
[fee_type] =>
[merge_id] => a87ff679a2f3e71d9181a67b7542122c
[total_paid] => 0
[total_remainder] => 0
)
[1] => Array
(
[client_id] => 5
[company_name] => company111_name
[id] => 6
[fee] => 55.5
[year] => 2010
[quarter] => 2
[date_inserted] => 1264949470
[description] => 2010 - Q2
[fee_type] =>
[merge_id] => a87ff679a2f3e71d9181a67b7542122c
[total_paid] => 0
[total_remainder] => 0
)
[2] => Array
(
[client_id] => 5
[company_name] => company111_name
[id] => 4
[fee] => 111
[year] => 2009
[quarter] => 4
[date_inserted] => 1264948583
[description] => 2009 - Q4
[fee_type] =>
[merge_id] =>
[total_paid] => 0
[total_remainder] => 0
)
[3] => Array
(
[client_id] => 5
[company_name] => company111_name
[id] => 7
[fee] => 55.5
[year] => 2010
[quarter] => 3
[date_inserted] => 1264949470
[description] => 2010 - Q3
[fee_type] =>
[merge_id] =>
[total_paid] => 0
[total_remainder] => 0
)
)
Code
$merger = $data['search']['0']['merge_id'];
$i = 0;
foreach($data['search'] as $fee)
{
if($fee['merge_id'] == $merger)
{
//bump up & merge arrays
???
}
$merger = $fee['merge_id'];
$i++;
}
You can use the ID as key to put all items with the same ID in the same array:
$merged = array();
foreach ($data['search'] as $fee) {
if ($fee['merge_id'] == '') {
continue;
}
if (!isset($merged[$fee['merge_id']])) {
$merged[$fee['merge_id']] = array();
}
$merged[$fee['merge_id']][] = $fee;
}
$merged = array_values($merged);
Notice that this will skip the items with an empty merge ID. You could also use a default merge ID in that case by replacing continue; with $fee['merge_id'] = 0;.
foreach($array as $p)
$result[$p['merge_id']][] = $p;

Categories