Sort multidimensional array of objects - php

I have seen so many example at stackoverflow to sort multidimensional array of object like
Sort array of objects
Sort array of objects by object fields
But none them could help me to sort my multidimensional array of objects given below
SimpleXMLElement Object
(
[request] => SimpleXMLElement Object
(
[address] => test
[citystatezip] => New York
)
[message] => SimpleXMLElement Object
(
[text] => Request successfully processed
[code] => 0
)
[response] => SimpleXMLElement Object
(
[results] => SimpleXMLElement Object
(
[result] => Array
(
[0] => SimpleXMLElement Object
(
[zpid] => 27965224
[links] => SimpleXMLElement Object
(
[homedetails] => test
[graphsanddata] =>test
[mapthishome] => test
[comparables] => test
)
[address] => SimpleXMLElement Object
(
[street] => test
[zipcode] => test
[city] => test
[state] => NY
[latitude] => 29.802114
[longitude] => -95.504244
)
[zestimate] => SimpleXMLElement Object
(
[amount] => 342911
[last-updated] => 11/27/2014
[oneWeekChange] => SimpleXMLElement Object
(
[#attributes] => Array
(
[deprecated] => true
)
)
[valueChange] => 5766
[valuationRange] => SimpleXMLElement Object
(
[low] => 312049
[high] => 373773
)
[percentile] => 0
)
[rentzestimate] => SimpleXMLElement Object
(
[amount] => 5177
[last-updated] => 11/24/2014
[oneWeekChange] => SimpleXMLElement Object
(
[#attributes] => Array
(
[deprecated] => true
)
)
[valueChange] => 370
[valuationRange] => SimpleXMLElement Object
(
[low] => 3417
[high] => 7041
)
)
[localRealEstate] => SimpleXMLElement Object
(
[region] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 271582
[type] => neighborhood
[name] => test
)
[links] => SimpleXMLElement Object
(
[overview] => test
[forSaleByOwner] => test
[forSale] => test
)
)
)
)
[1] => SimpleXMLElement Object
[2] => SimpleXMLElement Object
[3] => SimpleXMLElement Object
..............................
..............................
)
)
)
)
I need to sort the above array on the basis of key amount in descending order. But the problem is amount key exist under two different parent keys "zestimate" and "rentzestimate".
i have tried the following function but it did not work:
public function my_comparison($a, $b) {
if ($a->amount == $b->amount) {
return 0;
}
return ($a->amount < $b->amount) ? -1 : 1;
}
Any help?
Thanks in advance

response->results->result is an array of SimpleXMLElement objects. You want to sort the array based on the inner zestimate->amount property of the element in descending order.
You have to write a comparison function that accepts SimpleXMLElement objects and, because you want a descending order, returns 1 if the zestimate->amount property of the first object is less than that of the second, -1 if it's greater and 0 if it's equal:
public function my_comparison(SimpleXMLElement $a, SimpleXMLElement $b) {
if ($a->zestimate->amount == $b->zestimate->amount) {
return 0;
}
return ($a->zestimate->amount < $b->zestimate->amount) ? 1 : -1; // note the signs
}

Related

Cant access tag name inside SimpleXMLObject

This is the print out from the variable $baseTypeDerivedDataTypeRefModel and is as far as I've got with getting the value I need. I need to extract the value int16, int64 etc from the SimpleXMLObject I've used $baseTypeDerivedDataTypeRefModel[0] and
$baseTypeDerivedDataTypeRefModel->getName() and a bunch of other stuff and cant get it to work, I know its probably something simple but its driving me crazy!
SimpleXMLElement Object ( [int16] => SimpleXMLElement Object ( [range] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) [ranges] => SimpleXMLElement Object ( [subrange] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) ) [multiplicationFactor] => 2 [resolution] => 2 ) )
SimpleXMLElement Object ( [int64] => SimpleXMLElement Object ( [range] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) [ranges] => SimpleXMLElement Object ( [subrange] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) ) [multiplicationFactor] => 2 [resolution] => 2 ) )
SimpleXMLElement Object ( [int16] => SimpleXMLElement Object ( [range] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) [ranges] => SimpleXMLElement Object ( [subrange] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) ) [multiplicationFactor] => 2 [resolution] => 2 ) )
SimpleXMLElement Object ( [uint8] => SimpleXMLElement Object ( ) )
SimpleXMLElement Object ( [int16] => SimpleXMLElement Object ( [range] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) [ranges] => SimpleXMLElement Object ( [subrange] => SimpleXMLElement Object ( [min] => 1 [max] => 10 ) ) [multiplicationFactor] => 2 [resolution] => 2 ) )
SimpleXMLElement Object ( [string] => SimpleXMLElement Object ( ) )
<derivedDataType name="DerivedIntDatatypeU16">
<description>Random Desc </description>
<baseType>
<int16>
<range>
<min>1</min>
<max>10</max>
</range>
<ranges>
<subrange>
<min>1</min>
<max>10</max>
</subrange>
</ranges>
<multiplicationFactor>2</multiplicationFactor>
<resolution>2</resolution>
</int16>
</baseType>
</derivedDataType>
Since you never know how many items "baseType" has (it is XML, after all), you could do this to get the name of the first item:
$xmlstring = '<derivedDataType name="DerivedIntDatatypeU16"> ... </derivedDataType>';
$xml = new SimpleXMLElement($xmlstring);
// Cast the SimpleXMLObject as an array
$list = (array) $data->baseType;
// Reset the array pointer (so we know we're at the start of the array)
reset($list);
// Get the key name of the first element
$name = key($list);
This fetches the baseType list, casts it as an array and then gets the key of the first array element.
There might be (or most likely are) better ways to do this, but it works.

Access data in an array

What I want to do is read the information and be able to get the data of each game, so which teams played, who won and etc. I've tried everything but can't seem to do this.
This is my data structure:
stdClass Object (
[_links] => Array (
[0] => stdClass Object (
[self] => http://api.football-data.org/alpha/soccerseasons/354/fixtures
)
[1] => stdClass Object (
[soccerseason] => http://api.football-data.org/alpha/soccerseasons/354
)
)
[count] => 10
[fixtures] => Array (
[0] => stdClass Object (
[_links] => stdClass Object (
[self] => stdClass Object (
[href] => http://api.football-data.org/alpha/fixtures/137842
)
[soccerseason] => stdClass Object (
[href] => http://api.football-data.org/alpha/soccerseasons/354
)
[homeTeam] => stdClass Object (
[href] => http://api.football-data.org/alpha/teams/338
)
[awayTeam] => stdClass Object (
[href] => http://api.football-data.org/alpha/teams/70
)
)
[date] => 2015-01-17T15:00:00Z
[status] => FINISHED
[matchday] => 22
[homeTeamName] => Leicester City
[awayTeamName] => Stoke City FC
[result] => stdClass Object (
[goalsHomeTeam] => 0
[goalsAwayTeam] => 1
)
)
[1] => stdClass Object (
[_links] => stdClass Object (
[self] => stdClass Object (
[href] => http://api.football-data.org/alpha/fixtures/136840
)
[soccerseason] => stdClass Object (
[href] => http://api.football-data.org/alpha/soccerseasons/354
)
[homeTeam] => stdClass Object (
[href] => http://api.football-data.org/alpha/teams/72
)
[awayTeam] => stdClass Object (
[href] => http://api.football-data.org/alpha/teams/61
)
)
[date] => 2015-01-17T15:00:00Z
[status] => FINISHED
[matchday] => 22
[homeTeamName] => Swansea City
[awayTeamName] => Chelsea FC
[result] => stdClass Object (
[goalsHomeTeam] => 0
[goalsAwayTeam] => 5
)
)
)
)
For example: I'd like to know what the value for "homeTeamName","awayTeamName", "goalsHomeTeam", "goalsAwayTeam" ...
Its hard to tell because you didnt post the code you are using but i suspect you are confusing the structure type. What you posted is actually an object - an instance of stdClass and the items that look like array elements are in fact properties on that object. So you need to use the appropriate access method of ->propertyName as opposed to ['propertyName']:
// YES
echo $data->fixtures[0]->homeTeamName;
// NO
echo $data['fixtures'][0]['homeTeamName'];
So to get the data for each game (or what i presume to be the "game" items) you would do:
foreach ($data->fixtures as $game) {
echo $game->homeTeamName;
echo $game->awayTeamName;
echo $game->result->goalsHomeTeam;
echo $game->result->goalsAwayTeam;
// etc..
}
It also seems like this is the return value from an API parsed with json_decode(). If that is the case you can actually make it an array all the way through by passing true as the second argument to json_decode():
$data = json_decode($response, true);
foreach ($data['fixtures'] as $game) {
echo $game['homeTeamName'];
echo $game['awayTeamName'];
echo $game['result']['goalsHomeTeam'];
echo $game['result']['goalsAwayTeam'];
// etc..
}

Returning an array within multiple objects and arrays

I can't seem to figure out the correct syntax to print:
[Agriculture] => AGR
[Animals] => AN
[Arts and Humanities] => ART
within the $TOPIC object.
What makes this a bit more confusing is that $TOPIC is in an object that can be called in a different order than this example. So instead of [3] => stdClass Object, it could be [4] => stdClass Object, (or any number).
Some sample foreach syntax is included below; it doesn't work though.
stdClass Object
(
[123456] => stdClass Object
(
[required_actions] => Array
(
[1] => stdClass Object
(
[maxlength] =>
[value] => $MESSAGE
[options_hash] =>
)
[2] => stdClass Object
(
[maxlength] =>
[value] => $NAME_PREFIX
[options_hash] => stdClass Object
(
[Ms.] => Ms.
[Mrs.] => Mrs.
[Mr.] => Mr.
)
)
[3] => stdClass Object
(
[maxlength] =>
[value] => $TOPIC
[options_hash] => stdClass Object
(
[Agriculture] => AGR
[Animals] => AN
[Arts and Humanities] => ART
)
)
)
)
)
foreach ($json->123456->required_actions as $info) {
echo $info->value => $TOPIC->options_hash;
}
The solution is to search for the parent object by value, and then request the child object's array. Here is what I used:
foreach ($json->123456->required_actions as $info) {
if ('$TOPIC' == $info->value) {
print_r($info->options_hash);
}
}

Access part of SimpleXMLElement Object - PHP

I need to loop through the items as an array within the SimpleXMLElement Object below but cannot seem to access it using $order->order->order->items. I can access the delivery and billing addresses using the same format, ie. $order->order->order->delivery_address and expected to get to the items array in the same way. However, I get an empty SimpleXMLElement Object when I print_r($order->order->order->items)
SimpleXMLElement Object
(
[order] => SimpleXMLElement Object
(
[id] => 860268
[shopkeeper_orderno] => 1001
[customer] => 797476
[creationdate] => Apr 19 2012 10:36:38:100AM
[reference] => k2koju45rmaqfl45n20xbkmq
[net] => 1500
[vat] => 17.5
[status] => 0
[isnew] => 1
[deductions] => 0
[postage] => 1
[paymentmethod] => PayPal
[instructions] => SimpleXMLElement Object
(
)
[errors] => SimpleXMLElement Object
(
)
[kashflow_synch] => 0
[order] => Array
(
[0] => SimpleXMLElement Object
(
[billing_address] => SimpleXMLElement Object
(
[0] =>
)
)
[1] => SimpleXMLElement Object
(
[delivery_address] => SimpleXMLElement Object
(
[0] =>
)
)
[2] => SimpleXMLElement Object
(
[items] => Array
(
[0] => SimpleXMLElement Object
(
[id] => 1285158
[headerID] => 860268
[productID] => 4867690
[description] => TEST ORDERING PF NODES - Special Offer Price
[net] => 1400
[vat] => 0
[qty] => 1
[formID] => -1
)
[1] => SimpleXMLElement Object
(
[id] => 1285159
[headerID] => 860268
[productID] => 4959678
[description] => Wedding dress
[net] => 100
[vat] => 17.5
[qty] => 1
[formID] => -1
)
)
)
)
[postage_tax] => 0
[dispatched] => 0
[paybyotherid] => -1
[ip] => 81.168.43.121
[wheredidyouhearid] => -1
)
)
EDIT: I just saw you made a mistake with the naming, the parent needs to be called <orders> and the sub items <order>
The SimpleXMLElement seems to be empty, in fact it's usually filled but not displayed when dumping (whoever thought of this crazy behaviour)
Can you try this?
foreach($order->orders->order as $order) { // should be orders then
echo $item->getName();
}
Or try it with SimpleXMLElement::children()
your items are actually on the second offset of the order array.
I'd just use the xPath to process these.
foreach($xmlObject->xpath('/order/order[2]/items') as $item)
{
// Do something with my $item
}
You can use a loop like the one below, then all you need to do is $items->id
foreach($order->children()->children()->items as $items)
{
}
Using Dan Lees suggestion I tried SimpleXMLElement::children() and did the below which works
foreach ($order->children() as $order) {
foreach ($order->children() as $order_details) {
foreach ($order_details->children() as $order_items) {
echo $order_items->id;
}
}
}

Foreach loop with mixed stdClass objects and arrays

Here I have an output from a website using Soap
stdClass Object
(
[page] => 0
[items] => 3
[total] => 3
[saleItems] => stdClass Object
(
[saleItem] => Array
(
[0] => stdClass Object
(
[reviewState] => open
[trackingDate] => 2011-11-03T01:06:43.547+01:00
[modifiedDate] => 2011-11-03T01:06:43.677+01:00
[clickDate] => 2011-10-30T22:57:57.383+01:00
[adspace] => stdClass Object
(
[_] => Beslist.nl [id] => 1437603
)
[admedium] => stdClass Object
(
[_] => 001. Program logo
[id] => 535098
)
[program] => stdClass Object
(
[_] => Zavvi NL
[id] => 8991
)
[clickId] => 1565847253976339456
[clickInId] => 0
[amount] => 40.45
[commission] => 2.83
[currency] => EUR
[gpps] => stdClass Object
(
[gpp] => Array
(
[0] => stdClass Object
(
[_] => shoplink
[id] => zpar0
)
)
)
[trackingCategory] => stdClass Object
(
[_] => Default
[id] => 45181
)
[id] => 46a4f84a-ba9a-45b3-af86-da5f3ec29648
)
)
)
)
I want to have the data (with a foreach loop) from program, commission and gpp->_. I can get the data from program and commission like this:
foreach ($sales->saleItems->saleItem as $sale) {
$programma = $sale->program->_;
$commissie = $sale->commission;
}
Works like a charm. However I can't get the data from the gpp->_ (want to have shoplink as result). I currently have:
foreach ($sales->saleItems->saleItem->gpps->gpp as $tracking) {
echo $tracking->_;
}
I get the error "Trying to get property of non-object". I've tried lots if variations and can't get it to work. Think I'm really close. Anyone has a solution?
This should work
foreach ($sales->saleItems->saleItem as $sale) {
foreach($sale->gpps->gpp as $tracking) {
echo $tracking->_;
}
As saleItem is an array, you won't be able to use chaining on it.

Categories