I've read what I've found on Stackoverflow and am still unclear on this.
I have an array of SimpleXML objects something like this:
array(2) {
[0]=>
object(SimpleXMLElement)#2 (2) {
["name"]=>
string(15) "Andrew"
["age"]=>
string(2) "21"
}
[1]=>
object(SimpleXMLElement)#3 (2) {
["name"]=>
string(12) "Beth"
["age"]=>
string(2) "56"
}
}
And I want to be able to sort by whatever column, ascending or descending. Something like:
sort($data, 'name', 'asc');
Where I can pass in the above array of objects and sort by the value of whichever key I like.
For reference, a similar .NET solution would be along these lines:
XmlSortOrder order = XmlSortOrder.Ascending;
if ( sortDirection == "asc" ) {
order = XmlSortOrder.Ascending;
}
expression.AddSort( columnSortingOn + "/text()", order,
XmlCaseOrder.UpperFirst, "en-us", XmlDataType.Text );
I've seen people say
"Use usort"
Followed by a basic example from the PHP manual but this doesn't really explain it. At least not to me. I've also seen people suggest using an external library like SimpleDOM but I want to avoid using something external for this (seemingly, though I cannot yet solve it) little thing.
Any help is appreciated, Thanks!
I guess the people suggesting to use SimpleDOM would be me. :)
I've written SimpleDOM::sort() exactly for that situation, because in order to sort SimpleXMLElements by an arbitration expression (or arbitrary expressions) you need to use array_multisort()
which is boring and won't teach you anything useful.
Here's the short version of how it works: first you create a proxy array of key=>value pairs corresponding to each SimpleXMLElement and the value with which they'll be sorted. In your example, if you want to sort them by <age/>
, the array would be array(21, 56)
. Then you call array_multisort()
with the "proxy array" as first argument, followed by any number of sorting modifiers such as SORT_DESC or SORT_NUMERIC then finally the array you want to sort, which will be passed by reference.
You will end up with something like that:
$nodes = array(
new SimpleXMLElement('<person><name>Andrew</name><age>21</age></person>'),
new SimpleXMLElement('<person><name>Beth</name><age>56</age></person>')
);
function xsort(&$nodes, $child_name, $order = SORT_ASC)
{
$sort_proxy = array();
foreach ($nodes as $k => $node)
{
$sort_proxy[$k] = (string) $node->$child_name;
}
array_multisort($sort_proxy, $order, $nodes);
}
xsort($nodes, 'name', SORT_ASC);
print_r($nodes);
xsort($nodes, 'age', SORT_DESC);
print_r($nodes);
But really, instead of burdening yourself with more code you'll have to maintain and possibly ending up rewriting array_multisort()
in userspace, you should leverage existing solutions. There's nothing interesting in such a sorting algorithm/routine, your time would be better spent on something that doesn't already exist.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With