Sort an Array of Objects within Array by value - php

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 :)

Related

search inside arrays with condition in php

I have an api with a list of arrays inside one array and each array inside this array it has one key [attributes] and inside this key one array with key [CITY_NAME]
this is my array coming from api
this array number is 0 but every day this number is changed and my figures come wrong, what is the good way to always have my city figures using the key [CITY_NAME]
I am fetching the data using this code
$json = file_get_contents($url);
$json_data = json_decode($json, true);
$data = $json_data['features'];
$mycity = $data[0]['attributes'];
Array
(
[0] => Array
(
[attributes] => Array
(
[CITY_NAME] => city1
[Name] => city1
[ADMIN_NAME] => city1
[POP_CLASS] => 5,000,000 to10,000,000
[Population] => 7676654
[Population_Data_Source] => Wikipedia
[Population_Data_Date] => 2018
[CityID] => 14
[Longitude] => 46.7614868685786
[Latitude] => 24.7388786516234
[Confirmed] => 0
[Recovered] => 0
[Deaths] => 0
[Active] => 0
[Tested] => 0
[Name_Eng] => city1
[Join_Count] => 61
[Confirmed_SUM] => 5152
[Deaths_SUM] => 9
[Recovered_SUM] => 1407
[Active_SUM] => 3736
[Tested_SUM] => 376607
[ObjectId] => 14
)
)
[1] => Array
(
[attributes] => Array
(
[CITY_NAME] => city2
[Name] => city2
[ADMIN_NAME] => city2
[POP_CLASS] => 1,000,000 to 5,000,000
[Population] => 1675368
[Population_Data_Source] => Wikipedia
[Population_Data_Date] => 2010
[CityID] => 9
[Longitude] => 39.8148987363852
[Latitude] => 21.4273876500039
[Confirmed] => 0
[Recovered] => 0
[Deaths] => 0
[Active] => 0
[Tested] => 0
[Name_Eng] => city2
[Join_Count] => 59
[Confirmed_SUM] => 6848
[Deaths_SUM] => 85
[Recovered_SUM] => 1145
[Active_SUM] => 5618
[Tested_SUM] => 0
[ObjectId] => 9
)
)
Since I may have misunderstood and you may have many, just build a new array with CITY_NAME:
foreach($data as $values) {
$result[$values['attributes']['CITY_NAME']] = $values['attributes'];
}
Now you can access by CITY_NAME:
echo $result['city1']['Population'];
This might be easier. Extract all attributes from all arrays into an array, then create an array from that indexed by CITY_NAME:
$data = array_column(array_column($json_data['features'], 'attributes'),
null, 'CITY_NAME');

How to split array data returned from json string in php

I have json return string like given below. I want to extract cancellation Policy list of objects like cutoff Time and refund In Percentage. I tried using for-loop but it didn't help me. Can you please help me on extracting this.
Array (
[apiStatus] => Array ( [success] => 1 [message] => SUCCESS ) <br>
[apiAvailableBuses] => Array ( <br>
[0] => Array ( [droppingPoints] => [availableSeats] => 41 <br>[partialCancellationAllowed] => [arrivalTime] => 08:00 AM <br>
[cancellationPolicy] => [<br>
{"cutoffTime":"1","refundInPercentage":"10"},<br>
{"cutoffTime":"2","refundInPercentage":"50"},<br>
{"cutoffTime":"4","refundInPercentage":"90"}<br>
] <br>
[boardingPoints] => Array ( [0] => Array ( [time] => 09:00PM [location] => Ameerpet,|Jeans Corner 9687452130 [id] => 6 ) [1] => Array ( [time] => 09:15PM [location] => S.R Nagar,S.R Nagar [id] => 2224 ) [2] => Array ( [time] => 09:10PM [location] => Kondapur,Toyota Show room [id] => 2244 ) ) [operatorName] => Deepak Travels [departureTime] => 9:00 PM [mTicketAllowed] => [idProofRequired] => [serviceId] => 6622 [fare] => 800 [busType] => 2+1 Hi-Tech Non A/c [routeScheduleId] => 6622 [commPCT] => 0 [operatorId] => 213 [inventoryType] => 0 ) <br>
[1] => Array ( [droppingPoints] => [availableSeats] => 41 [partialCancellationAllowed] => [arrivalTime] => 07:00 AM <br>
[cancellationPolicy] => [<br>
{"cutoffTime":"1","refundInPercentage":"10"},<br>
{"cutoffTime":"2","refundInPercentage":"50"},<br>
{"cutoffTime":"4","refundInPercentage":"90"}<br>
] <br>
[boardingPoints] => Array ( [0] => Array ( [time] => 09:10PM [location] => Ameerpet,|Jeans Corner [id] => 6 ) [1] => Array ( [time] => 09:00PM [location] => S.R Nagar,S.R Nagar [id] => 2224 ) [2] => Array ( [time] => 08:30PM [location] => KUKATPALLY,JNTU [id] => 2230 ) ) [operatorName] => Dhanunjayabus [departureTime] => 9:00 PM [mTicketAllowed] => [idProofRequired] => [serviceId] => 6743 [fare] => 900 [busType] => VOLVO [routeScheduleId] => 6743 [commPCT] => 0 [operatorId] => 233 [inventoryType] => 0 )
)
)
Use a foreach() for it like so:
foreach ($your_response['apiAvailableBuses'] as $el) {
$cancellationPolicy[] = $el['cancellationPolicy'];
}
Try this:
foreach($data['apiStatus']['apiAvailableBuses'] as $item) {
foreach($item['cancellationPolicy'] as $key => $json) {
$jsonDecoded = json_decode($json, true);
// And you will have access to the data like this
// $jsonDecoded['cutoffTime'];
// $jsonDecoded['refundInPercentage'];
}
}
$response = json_decode($apiResponse);
$cancellationPolicies = [];
foreach ($response->apiAvailableBuses as $availableBus) {
$cancellationPolicies[] = $availableBus['cancellationPolicy'];
// if you want to display something you can simply do it like this;
echo $availableBus['cancellationPolicy']->cutoffTime;
}

How to sort an array of objects by a property of each object

I have an array of data returned from the eventbrite.com api stored in a variable called $restrictedEvents which looks like the data below. This is representative of just one event for the purposes of pasting here but it has a about 80 stdClass Objects like this in the full array.
I want to sort this array alphabetically by the [title] key in each stdClass Object. I have tried using:
usort($restrictedEvents, "title");
However this returns the following error:
Warning: usort() [function.usort]: Invalid comparison function in model.php on line 109
My guess is it cannot find the title key as this is in the next level down. Any pointers on where I am going wrong and how I can sort by the title would be greatly appreciated. Many thanks.
Array
(
[4791063199] => stdClass Object
(
[box_header_text_color] => 393837
[link_color] => EE6600
[box_background_color] => FFFFFF
[box_border_color] => D9D4D0
[timezone] => Europe/London
[organizer] => stdClass Object
(
[url] => http://www.eventbrite.com/org/2866607767
[description] =>
[long_description] =>
[id] => 2866607767
[name] => B&Q Manifestival
)
[background_color] => E3DFDC
[id] => 4791063199
[category] =>
[box_header_background_color] => F0ECE9
[capacity] => 20
[num_attendee_rows] => 0
[title] => Closed Event Test
[start_date] => 2012-11-07 19:00:00
[status] => Live
[description] => Lorem ipsum
[end_date] => 2012-11-07 21:00:00
[tags] =>
[timezone_offset] => GMT+0000
[text_color] => 393837
[title_text_color] =>
[password] =>
[tickets] => Array
(
[0] => stdClass Object
(
[ticket] => stdClass Object
(
[description] =>
[end_date] => 2012-11-07 17:00:00
[min] => 1
[max] => 1
[price] => 0.00
[quantity_sold] => 0
[visible] => true
[currency] => GBP
[quantity_available] => 20
[type] => 0
[id] => 15940001
[name] => Manifestival Event
)
)
)
[created] => 2012-11-07 10:40:36
[url] => http://www.eventbrite.com/event/4791063199
[box_text_color] => 393837
[privacy] => Private
[venue] => stdClass Object
(
[city] =>
[name] => HR Training Room
[country] =>
[region] =>
[longitude] => 0
[postal_code] =>
[address_2] =>
[address] =>
[latitude] => 0
[country_code] =>
[id] => 2619469
[Lat-Long] => 0.0 / 0.0
)
[modified] => 2012-11-07 10:47:20
[repeats] => no
)
The second paramater to usort should be a function. See http://php.net/manual/en/function.usort.php. You would need to pass it a function like:
function cmp($a, $b)
{
return strcmp($a->title, $b->title);
}
I think you would then call it like usort($restrictedEvents, "cmp");.
You can do it with ouzo goodies:
$result = Arrays::sort($restrictedEvents, Comparator::compareBy('title'));
http://ouzo.readthedocs.org/en/latest/utils/comparators.html
The second parameter to usort is a function, not a key name. The function gets passed two elements of the array being sorted and returns a value indicating how those two elements should be ordered with respect to each other: -1 if the order in which they're passed to the function is correct, 1 if it's reversed, and 0 if it doesn't matter (the two elements are equal as far as the comparison goes). Here's an example for your case:
usort($restrictedEvents,
function($a, $b) { return strcmp($a->title, $b->title); });
If you're on an older PHP (before 5.3.0, which introduced anonymous functions), then you have to give the comparison function a name and pass that name as a string to usort:
function titlecmp($a, $b) {
return strcmp($a->title, $b->title);
}
usort($restrictedEvents, "titlecmp");
Usually something like this is achieved via a second array with $keyToSort => $id, sort this array via the standart sort functions or your own, then you have a conversion to your first array
using this, the depth of your array is limitless.

complicated multidimentional array process with foreach

im having a problem trying to process this array tried several different ways but none where right, here's the array
Array (
[search] => Array (
[response] => Array (
[errors] =>
[number_of_hotels] => 1 of 1
)
[lr_rates] => Array (
[hotel] => Array (
[hotel_ref] => 3116
[hotel_currency] => [U] => USD
[hotel_rooms] => Array (
[room] => Array (
[ref] => 6382
[type] => 1
[type_description] => Standard
[sleeps] => 8
[rooms_available] =>
[adults] => 8
[children] =>
[breakfast] => false
[dinner] => false
[description] =>
[alternate_description] =>
[rack_rate] => 82.01
[date] => 19/08/201220/08/201221/08/2012
[numeric_hotelcurrencyprice] => FullFullFull
[formatted_date] => 19 August 201220 August 201221 August 2012
[price] => FullFullFull
[hotelcurrencyprice] => FullFullFull
[numeric_price] => FullFullFull
[requested_currency] => GBPGBPGBP
[numeric_hotelcurrencyprice] => FullFullFull
[available_online] => false
[minimum_nights] => 1
[bed_type] =>
[cancellation_policy] =>
[cancellation_days] =>
[cancellation_hours] =>
[room_terms] =>
)
[room] => Array (
[ref] => 6382
[type] => 1
[type_description] => Standard
[sleeps] => 8
[rooms_available] =>
[adults] => 8
[children] =>
[breakfast] => false
[dinner] => false
[description] =>
[alternate_description] =>
[rack_rate] => 82.01
[date] => 19/08/201220/08/201221/08/2012
[numeric_hotelcurrencyprice] => FullFullFull
[formatted_date] => 19 August 201220 August 201221 August 2012
[price] => FullFullFull
[hotelcurrencyprice] => FullFullFull
[numeric_price] => FullFullFull
[requested_currency] => GBPGBPGBP
[numeric_hotelcurrencyprice] => FullFullFull
[available_online] => false
[minimum_nights] => 1
[bed_type] =>
[cancellation_policy] =>
[cancellation_days] =>
[cancellation_hours] =>
[room_terms] =>
)
)
[cancellation_type] => First Night Stay Chargeable
[cancellation_policy] => 2 Days Prior to Arrival
[CityTax] => Array (
[TypeName] =>
[Value] =>
[OptedIn] =>
[IsCityTaxArea] =>
)
)
)
)
)
ok i need to traverse the array and create a loop so for every instance of room it will repeat the process then i need to extract the data from room array and use it to populate rows in MySQL there will be multiple instances of room this is the code i have so far which prints the names and values in the room array but it only gets one of the room arrays what can i do to set it up to read them all and i am also thinking this is too many for-each but don't seem to be able to traverse down ['']['']['']...
or by just using the associative name.
foreach($arr['search'] as $lr_rates) {
foreach($lr_rates['hotel'] as $hotel) {
foreach($hotel['room'] as $field => $value){
print $field;print $value;
}
}
}
it mite also be worth mentioning the values in these arrays are always fluctuating
you don't have to use so much foreach loops in your script as it not looks good. this is an associative array.
you can simply access associate array by using its keys. do some google for it.you can find many scripts on this.
foreach($arr as $search) {
foreach($search as $lr_rates) {
foreach($lr_rates as $hotel) {
foreach($hotel as $hotel_rooms) {
print_r($hotel_rooms['room'])
}
}
}
}
EDIT: These many foreach loops are just to make understand how to reach to room. You can also get the result directly ofcourse.
print_r($arr['search']['lr_rates']['hotel']['hotel_rooms']['room']);

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