I have an array of object with dynamic date and days. I want to sort array with days keys in php in the order of the days.
Given input like this:
array(
[17-08-2017] => stdClass Object
(
[days] => Thu
)
[21-08-2017] => stdClass Object
(
[days] => Mon
)
[22-08-2017] => stdClass Object
(
[days] => Tue
)
[23-08-2017] => stdClass Object
(
[days] => Wed
)
);
I want result like this:
array(
[21-08-2017] => stdClass Object
(
[days] => Mon
)
[22-08-2017] => stdClass Object
(
[days] => Tue
)
[23-08-2017] => stdClass Object
(
[days] => Wed
)
[17-08-2017] => stdClass Object
(
[days] => Thu
)
);
I know this is the stupid idea but how can I do this. Please help me.
convert your key to strtotime($key)
then apply ksort($dates) but it will eliminate the duplicate key.
Probably the same question
You need a custom sorting function.
$t = new DateTime('this week'); //Using this to hopefully adapt for locale wrt which day is first
$daysOrder = [];
for ($i=0;$i<7;$i++) {
$daysOrder [] = $t->format("D");
$t->add(new DateInterval("P1D"));
}
$daysOrder = array_flip($daysOrder); //Days as keys, order as values
Then you can sort:
$array = uasort($array, function ($x,$y) use ($daysOrder) {
//May need to do some checks here to determine if $x and $y are valid days
return $daysOrder[$x] <=> $daysOrder[$y]; //PHP 7 syntax
});
The PHP 5.x syntax would be something like:
return $daysOrder[$x] < $daysOrder[$y]?-1:($daysOrder[$x]==$daysOrder[$y]?0:1);
Related
Working against an API for an accounting system and wondering how to handle the return of fiscals years. I want to iterate each fiscal year, which is no problem if there are multiple fiscal years. However if there is only one fiscal year the returned object/array is slightly different, how should I handle this, ie how to identify the subarray?
//Example data if multiple fiscal years
stdClass Object
(
[GetFiscalYearsResult] => stdClass Object
(
[FiscalYear] => Array
(
[0] => stdClass Object
(
[Id] => 257c2e5e-2b5b-4eea-9405-775caef357d4
[StartingDate] => 2015-01-01T00:00:00Z
[EndingDate] => 2016-01-01T00:00:00Z
[IsLocked] =>
)
[1] => stdClass Object
(
[Id] => 376ce224-77ce-43cd-b3c4-a3703b1fc8bf
[StartingDate] => 2018-01-01T00:00:00Z
[EndingDate] => 2019-01-01T00:00:00Z
[IsLocked] =>
)
)
)
)
//Example data if one fiscal year
stdClass Object
(
[GetFiscalYearsResult] => stdClass Object
(
[FiscalYear] => stdClass Object
(
[Id] => f2712737-9c63-4c4b-b107-1b841985cffb
[StartingDate] => 2019-01-01T00:00:00Z
[EndingDate] => 2020-01-01T00:00:00Z
[IsLocked] =>
)
)
)
//Current php code for multiple fiscal years
$Result = $Service->GetFiscalYears();
foreach($Result->GetFiscalYearsResult->FiscalYear as $item=>$object) {
$YE = date('Y-m-d',(strtotime ( '-1 day' , strtotime ( $object -> EndingDate) ) ));
echo $YE
}
//EDIT With solution (identification of subarray with is_array)
$Result = $Service->GetFiscalYears();
if(is_array($Result->GetFiscalYearsResult->FiscalYear)){
foreach($Result->GetFiscalYearsResult->FiscalYear as $item=>$object) {
CODE
}
} else { //if only one fiscal year
CODE
}
This question already has answers here:
Sort array of objects by date field
(6 answers)
Closed 10 months ago.
I have a function which returns array of objects. This is my function
public function myFunction () {
$args = [
'post_type' => 'post',
];
$data = \WordPress\Query::get_posts($args);
$now = time();
foreach ($data as $key => $datas) {
$eventTime = $datas->endtime;
$eventTimeStr = strtotime($eventTime);
if ($eventTimeStr < $now) {
unset($data[$key]);
}
}
return $data;
}
This returns array of objects like so:
Array
(
[0] => WP_Post Object
(
[ID] => 14
[metadata] => Array
(
[post_title] => Event number 3
[starttime] => 24.11.2019
[endtime] => 25.11.2019
)
)
[1] => WP_Post Object
(
[ID] => 13
[metadata] => Array
(
[post_title] => Event number 1
[starttime] => 19.1.2017
[endtime] => 20.1.2017
)
)
[2] => WP_Post Object
(
[ID] => 10
[metadata] => Array
(
[post_title] => Event number 2
[starttime] => 19.1.2018
[endtime] => 20.1.2018
)
)
)
How can I sort the array by property "endtime" so that "Event number 1" is the first one on the list and "Event number 2" second etc. ?
I tried using usort-function inside myFunction() but didn't manage to succeed. Should I create another function outside of myFunction() and access the $data-variable from there? If so, how?
In myFunction() I have formatted the date to Unix Timestamp. I probably should use it?
as always, sorting algorithm uses a compare function behind the scene to sort the whole array by comparing two element, for sorting complex stuff like this, one should write compare function and define the logic there for ordering
function compare($a, $b)
{
return strtotime($a->metadata['endtime']) < strtotime($b->metadata['endtime']);
}
usort($yourarray, 'compare');
I'm creating an array of objects (or trying to) that looks like this:
Array
(
[1] => stdClass Object
(
[date] => 2016-09-28
)
[5] => stdClass Object
(
[date] => 2016-09-28
)
[2] => stdClass Object
(
[date] => 2016-09-29
)
[0] => stdClass Object
(
[date] => 2016-09-30
)
[4] => stdClass Object
(
[date] => 2016-09-30
)
[3] => stdClass Object
(
[date] => 2016-09-30
)
)
The trouble that I'm having is that I need can't work out how to check if an object with date->$date already exists.
I need an array of 'days' that I can then go on to add workshops to the corresponding days, not to a new object each time.
Can anyone make a suggestion?
EDIT
To put this in context, I'm iterating through a bunch of wordpress posts (of type 'workshop' in this case) which all have a piece of date meta. On my way through the loop I want to
Get the date(day)
Check if that date exists in the array
If not, add the date to the array
Then add the workshop object to that date array
What I should therefor end up with is an array containing three or four unique dates, each with an array of workshop objects.
Array(
Date 1(
Workshop(
Title, etc
),
Workshop()
)
Date 2(
Workshop(
Title, etc
)
Workshop()
)
)
My apologies, I'm sure my structure is off - this is a little advanced for me. Thanks for looking.
What you need is something like this. You can have a function to group your result.
function groupWorkShopsByDate($first_array){
$result_arr = array();
foreach( $first_array as $workShop ){
$result_arr[ $workShop->date ][] = $workShop;
}
return $result_arr;
}
Hope this helps!
---array $points----
Array
(
[0] => Array
(
[0] => 2011-10-02 05:30:00
[1] => 20
)
[1] => Array
(
[0] => 2011-10-04 09:30:00
[1] => 12
)
[2] => Array
(
[0] => 2011-10-01 13:30:00
[1] => 25
)
[3] => Array
(
[0] => 2011-10-03 02:30:00
[1] => 31
)
)
I have an array at above and would like to sort this array by time. Then I used the code as following to sort and result is correct. However, if I changed the code time[$key] = $val[0] to $time = $val[0], the result is wrong.
Is there anyone can explain this to me? Many thanks!
foreach($points as $key=>$val){
$time[$key] = $val[0];
array_multisort($time, SORT_ASC, $points);
}
array_multisort sorts more than one array at once. However, it works on an array of columns, so the foreach loop is needed to get a column of the times. After building up this list, you can then perform the multisort. The $points array is ordered according to the indices in $times, as per this example in the docs.
However, you don't need to perform the sort inside the foreach, as that means the sort happens 4 times (in your example). It only needs to happen once:
foreach ($points as $key => $val) {
$time[$key] = $val[0];
}
array_multisort($time, SORT_ASC, $points);
The function uasort() takes a comparison callback function. You can use this to compare two timestamps.
$arr = array(
array('2011-10-02 05:30:00','20'),
array('2011-10-04 09:30:00','12'),
array('2011-10-01 13:30:00','25'),
array('2011-10-03 02:30:00','31')
);
function timecomp($a,$b)
{
// Subtracting the UNIX timestamps from each other.
// Returns a negative number if $b is a date before $a,
// otherwise positive.
return strtotime($b[0])-strtotime($a[0]);
}
uasort($arr,'timecomp');
print_r($arr);
The above code will return
(
[1] => Array
(
[0] => 2011-10-04 09:30:00
[1] => 12
)
[3] => Array
(
[0] => 2011-10-03 02:30:00
[1] => 31
)
[0] => Array
(
[0] => 2011-10-02 05:30:00
[1] => 20
)
[2] => Array
(
[0] => 2011-10-01 13:30:00
[1] => 25
)
)
What you want to do is (basic idea):
foreach($points as $key=>$val){
$time[$val[1]] = $val[0]; // $time will be an array of [ point => time ] pairs
}
asort( $time ); // sorts the array and maintains indexes
After this you have an array of point => time pairs, sorted by time. To get just the points, for instance do
$points = array_keys( $time );
I var_dump and array and got a value printed, how do i create an array from the result. the array is generated a method and i clearly dont know the structure of the array.
Array ( [0] => gapiReportEntry Object ( [metrics:gapiReportEntry:private] => Array ( [visits] => 4 ) [dimensions:gapiReportEntry:private] => Array ( [year] => 2011 [month] => 07 [day] => 20 ) ) [1] => gapiReportEntry Object ( [metrics:gapiReportEntry:private] => Array ( [visits] => 32 ) [dimensions:gapiReportEntry:private] => Array ( [year] => 2011 [month] => 07 [day] => 13 ) ))
the above is the var_dump result.
I tried to recreate it
$nuarr = array();
$nuarr[0] = array("metrics:gapiReportEntry:private"=>array("visits"=>4),"dimensions:gapiReportEntry:private"=>array("year"=>2011,"months"=>07,"day"=>20));
$nuarr[1] = array("metrics:gapiReportEntry:private"=>array("visits"=>10),"dimensions:gapiReportEntry:private"=>array("year"=>2011,"months"=>07,"day"=>10));
but it doesn't return the same var_dunp value.
Could anyone structure the array for me...
Just assign the new array using assignment operator =
$nuarr = $first_array;
Now the $nuarr is an identical copy of your $first_array.
You can also use the var_export
$nuarr = var_export($first_array, true);
You don't mention why you want to do this. If what you need is just an array-to-string and vice versa mechanism, consider using serialize() and unserialize() rather than var_dump().
If you want to print out an array so that you can clearly see its structure, couldn't you do the following?
echo '<pre>'.print_r($array,1)',</pre>';
I know it isn't using var_dump(), but it would produce the desired result, wouldn't it?