qamargrt Posted March 4, 2012 Share Posted March 4, 2012 I have the following php array structure and couldnot able to sort it according to the overall points. My code is reading an xml file using simplexml. Any help would be appreciated. Array ( [0] => SimpleXMLElement Object ( [played] => 0 [won] => 0 [drawn] => 0 [lost] => 0 [overallpoints] => 0 ) [1] => SimpleXMLElement Object ( [played] => 6 [won] => 3 [drawn] => 0 [lost] => 3 [overallpoints] => 9 ) [2] => SimpleXMLElement Object ( [played] => 3 [won] => 1 [drawn] => 0 [lost] => 2 [overallpoints] => 3 ) [3] => SimpleXMLElement Object ( [played] => 0 [won] => 0 [drawn] => 0 [lost] => 0 [overallpoints] => 0 ) [4] => SimpleXMLElement Object ( [played] => 2 [won] => 1 [drawn] => 0 [lost] => 1 [overallpoints] => 3 ) } Quote Link to comment Share on other sites More sharing options...
blacknight Posted March 4, 2012 Share Posted March 4, 2012 this is a function i use to sort my arrays [code function sksort(&$array, $subkey="id", $sort_ascending=false) { if (count($array)) $temp_array[key($array)] = array_shift($array); foreach($array as $key => $val){ $offset = 0; $found = false; foreach($temp_array as $tmp_key => $tmp_val) { if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { $temp_array = array_merge( (array)array_slice($temp_array,0,$offset), array($key => $val), array_slice($temp_array,$offset) ); $found = true; } $offset++; } if(!$found) $temp_array = array_merge($temp_array, array($key => $val)); } if ($sort_ascending) $array = array_reverse($temp_array); else $array = $temp_array; } sksort($yourarrayname,'overallpoints'); and its done no need to make the assign the array to a new var it keeps the old one Quote Link to comment Share on other sites More sharing options...
qamargrt Posted March 4, 2012 Author Share Posted March 4, 2012 Thank you for your response but it did not work with that function. I am using the code below to sort and print xml doc. //SimpleXML Element $teams = new SimpleXMLElement('C:\\teams.xml',NULL,true); $abs = array(); function sksort(&$array, $subkey="id", $sort_ascending=false) { if (count($array)) $temp_array[key($array)] = array_shift($array); foreach($array as $key => $val){ $offset = 0; $found = false; foreach($temp_array as $tmp_key => $tmp_val) { if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { $temp_array = array_merge( (array)array_slice($temp_array,0,$offset), array($key => $val), array_slice($temp_array,$offset) ); $found = true; } $offset++; } if(!$found) $temp_array = array_merge($temp_array, array($key => $val)); } if ($sort_ascending) $array = array_reverse($temp_array); else $array = $temp_array; } // echo '<pre>'; // print_r($teams); foreach ($teams as $team) { $abs[] = $team; } echo '<pre>'; //sksort($abs); print_r($abs); Quote Link to comment Share on other sites More sharing options...
creata.physics Posted March 4, 2012 Share Posted March 4, 2012 If that exact code you posted is what you are using then you aren't even calling the function since it's commented out. Also, you may not need to do all that, this should work: $teams = new SimpleXMLElement('C:\\teams.xml',NULL,true); $abs = array(); foreach ( $teams as $team ) { arsort( $team ); $abs[] = $team; } echo '<pre>'; print_r( $abs ); echo '</pre>'; Quote Link to comment Share on other sites More sharing options...
blacknight Posted March 4, 2012 Share Posted March 4, 2012 //sksort($abs); you did not state the array key to sort by you have to include the ,'overallpoints' or the function does nothing Quote Link to comment Share on other sites More sharing options...
qamargrt Posted March 4, 2012 Author Share Posted March 4, 2012 I did use the commented one. It tested it with comment and with out comment but the result was same. Also If I use the code below you posted it gives warnings and doesnot effect at all. One more thing suppose if it sort the array with this code how the output would be because I need to sort according to overallpoints? Have a look at the XML below <?xml version="1.0" encoding="UTF-8" standalone="no"?> <teams> <dantooinedestroyers><played>6</played><won>3</won><drawn>0</drawn><lost>3</lost><overallpoints>9</overallpoints></dantooinedestroyers> <waylandwarriors><played>3</played><won>1</won><drawn>0</drawn><lost>2</lost><overallpoints>3</overallpoints></waylandwarriors><coruscantcrusaders><played>2</played><won>1</won><drawn>0</drawn><lost>1</lost><overallpoints>3</overallpoints></coruscantcrusaders><tatooinetraverllers><played>1</played><won>1</won><drawn>0</drawn><lost>0</lost><overallpoints>3</overallpoints></tatooinetraverllers><romulasrejects><played>1</played><won>0</won><drawn>0</drawn><lost>1</lost><overallpoints>0</overallpoints></romulasrejects><tottenhamskaro><played>1</played><won>0</won><drawn>0</drawn><lost>1</lost><overallpoints>0</overallpoints></tottenhamskaro><dynamonewearth><played>0</played><won>0</won><drawn>0</drawn><lost>0</lost><overallpoints>0</overallpoints></dynamonewearth><dagobahdragons><played>0</played><won>0</won><drawn>0</drawn><lost>0</lost><overallpoints>0</overallpoints></dagobahdragons><rurapenthemassive><played>0</played><won>0</won><drawn>0</drawn><lost>0</lost><overallpoints>0</overallpoints></rurapenthemassive><cardassiaprimewanderers><played>2</played><won>2</won><drawn>0</drawn><lost>0</lost><overallpoints>6</overallpoints></cardassiaprimewanderers></teams> Quote Link to comment Share on other sites More sharing options...
qamargrt Posted March 4, 2012 Author Share Posted March 4, 2012 I am sorry I forgot to add overall points in parameter but still did not work Here is the code now $teams = new SimpleXMLElement('C:\\teams.xml',NULL,true); $abs = array(); function sksort(&$array, $subkey="id", $sort_ascending=false) { if (count($array)) $temp_array[key($array)] = array_shift($array); foreach($array as $key => $val){ $offset = 0; $found = false; foreach($temp_array as $tmp_key => $tmp_val) { if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { $temp_array = array_merge( (array)array_slice($temp_array,0,$offset), array($key => $val), array_slice($temp_array,$offset) ); $found = true; } $offset++; } if(!$found) $temp_array = array_merge($temp_array, array($key => $val)); } if ($sort_ascending) $array = array_reverse($temp_array); else $array = $temp_array; } foreach ($teams as $team) { $abs[] = $team; } echo '<pre>'; sksort($abs,'overallpoints'); print_r($abs); and here is the output : Array ( [0] => SimpleXMLElement Object ( [played] => 6 [won] => 3 [drawn] => 0 [lost] => 3 [overallpoints] => 9 ) [1] => SimpleXMLElement Object ( [played] => 3 [won] => 1 [drawn] => 0 [lost] => 2 [overallpoints] => 3 ) [2] => SimpleXMLElement Object ( [played] => 2 [won] => 1 [drawn] => 0 [lost] => 1 [overallpoints] => 3 ) [3] => SimpleXMLElement Object ( [played] => 1 [won] => 1 [drawn] => 0 [lost] => 0 [overallpoints] => 3 ) [4] => SimpleXMLElement Object ( [played] => 1 [won] => 0 [drawn] => 0 [lost] => 1 [overallpoints] => 0 ) [5] => SimpleXMLElement Object ( [played] => 1 [won] => 0 [drawn] => 0 [lost] => 1 [overallpoints] => 0 ) [6] => SimpleXMLElement Object ( [played] => 0 [won] => 0 [drawn] => 0 [lost] => 0 [overallpoints] => 0 ) [7] => SimpleXMLElement Object ( [played] => 0 [won] => 0 [drawn] => 0 [lost] => 0 [overallpoints] => 0 ) [8] => SimpleXMLElement Object ( [played] => 0 [won] => 0 [drawn] => 0 [lost] => 0 [overallpoints] => 0 ) [9] => SimpleXMLElement Object ( [played] => 2 [won] => 2 [drawn] => 0 [lost] => 0 [overallpoints] => 6 ) ) Quote Link to comment Share on other sites More sharing options...
blacknight Posted March 4, 2012 Share Posted March 4, 2012 this si smaller and a lil simpler... note the 3 line xml -> php array converter... $xml = new SimpleXMLElement('teams.xml',NULL,true); $json = json_encode($xml); $array = json_decode($json,TRUE); echo '<pre>'; echo 'Befor<br>'; print_r($array); echo 'After<br>'; sksort($array,'overallpoints'); print_r($array); function sksort(&$array, $subkey="id", $sort_ascending=false) { if (count($array)) $temp_array[key($array)] = array_shift($array); foreach($array as $key => $val){ $offset = 0; $found = false; foreach($temp_array as $tmp_key => $tmp_val) { if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { $temp_array = array_merge( (array)array_slice($temp_array,0,$offset), array($key => $val), array_slice($temp_array,$offset) ); $found = true; } $offset++; } if(!$found) $temp_array = array_merge($temp_array, array($key => $val)); } if ($sort_ascending) $array = array_reverse($temp_array); else $array = $temp_array; } Quote Link to comment Share on other sites More sharing options...
kicken Posted March 4, 2012 Share Posted March 4, 2012 <?php function sortOverall($a, $b){ return $a->overall - $b->overall; } usort($arr, 'sortOverall'); Quote Link to comment Share on other sites More sharing options...
qamargrt Posted March 4, 2012 Author Share Posted March 4, 2012 THANK YOU VERY MUCHHHHH it works. To be honest I as a newbie I have the right to ask how is it working? Although it looks simple but its better to ask to clear the confusion. I recently started working on PHP feeling it very confusing but hope to get better with the passage of time. Thanks again. Below is the working code. $abs = array(); function sortOverall($a, $b) { return $b->overallpoints - $a->overallpoints; } foreach ($teams as $team=>$value) { $abs[$team] = $value; } echo '<pre>'; uasort($abs, 'sortOverall'); print_r($abs); Quote Link to comment Share on other sites More sharing options...
kicken Posted March 4, 2012 Share Posted March 4, 2012 usort is a function which will sort your array by comparing the items using a custom defined function. As PHP goes through the array it will call your function several times, each time giving it two different items of the array. What your function has to do is determine how they relate to one another and return a value that is either: < 0: meaning that the first item come before the second = 0: meaning that they are equal and the order does not matter. > 0: meaning that the second item comes before the first item. So for the comparison function we have: function sortOverall($a, $b){ return $b->overallPoints - $a->overallPoints; } Let say for the first round PHP calles that with $a being: SimpleXMLElement Object ( [played] => 2 [won] => 1 [drawn] => 0 [lost] => 1 [overallpoints] => 3 ) and $b being: SimpleXMLElement Object ( [played] => 6 [won] => 3 [drawn] => 0 [lost] => 3 [overallpoints] => 9 ) For the return value we have $b->overallpoints - $a->overallpoints = 9 - 3 = 6. Since 6 is > than zero, PHP will sort them as [$b, $a], putting $b first. Then on the next round we get $a=: SimpleXMLElement Object ( [played] => 6 [won] => 3 [drawn] => 0 [lost] => 3 [overallpoints] => 9 ) and $b= SimpleXMLElement Object ( [played] => 0 [won] => 0 [drawn] => 0 [lost] => 0 [overallpoints] => 0 ) The result from the sort function is -9, which results in $a coming before $b in the final array. This process continues until the array is fully sorted. If you want to know more about how the sort is actually done, php used the quicksort algorithm which is one of the most common generic algorithms. Quote Link to comment Share on other sites More sharing options...
qamargrt Posted March 4, 2012 Author Share Posted March 4, 2012 Thank you very much excellent description Now I understand the working. Cheers Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.