charlysole Posted June 17, 2017 Share Posted June 17, 2017 Hi everyone This is quite difficult to explain.... i have the following code: // Calculate total ordinal ranking. uasort($totals, "sort_totals"); $ordinal = 0; $last_ordinal = 0; $high_score = 0; $last_score = 100000; foreach ($totals as $uid => $u_object) { $ordinal++; if ($u_object['total'] < $last_score) { $last_ordinal = $ordinal; $last_score = $u_object['total']; if ( $ordinal == 1 ) { $high_score = $last_score; } } $totals[$uid]['ranking'] = $last_ordinal; $totals[$uid]['pts_back'] = $high_score - $last_score; } cache_set($cache_key, $totals); } $cache_totals[$cache_key] = $totals; } return $cache_totals[$cache_key]; } function sort_totals($a, $b) { if ($a['total'] > $b['total']) { return -1; } elseif ($a['total'] < $b['total']) { return 1; } else { if ($a['name'] < $b['name']) { return -1; } elseif ($a['name'] > $b['name']) { return 1; } else { return 0; } } } This code sorts the totals arranging them major to minor. And thats ok... it works. Now I also have another parameter called "exact" here: .... $u_object['exact'] Who contains an integer showing the number of times a user has matched the exact result. What i want to do is use$u_object['exact'] as a second arrangement parameter number... Example For the following stored data: User 1: 100 points, and 4 matches. User 2: 90 points, and 2 matches. User 4: 100 points and 7 matches. The result should be: User 4: 100 points and 7 matches. User 1: 100 points, and 4 matches. User 2: 90 points, and 2 matches. As you can see 2 the first sort is by total, and the second by matches How can i do this? Thanks in advice. And sorry for my poor english! Quote Link to comment Share on other sites More sharing options...
requinix Posted June 17, 2017 Share Posted June 17, 2017 $u_object is the same array as $a and $b in the comparison function (sort_totals). You have some branching logic in there to handle [total] and [name] so all you have to do is extend it with another comparison using [exact] in between. function sort_totals($a, $b) { if ($a['total'] > $b['total']) { return -1; } elseif ($a['total'] < $b['total']) { return 1; } else { if ($a['exact'] > $b['exact']) { return -1; } elseif ($a['exact'] < $b['exact']) { return 1; } else { if ($a['name'] < $b['name']) { return -1; } elseif ($a['name'] > $b['name']) { return 1; } else { return 0; } } } } Getting rather long, though, isn't it? The good news is that there's a much better way of doing all those comparisons, and it's possible because the return value from the function merely has to be negative, zero, or positive - not strictly -1, 0, or 1. For the numbers, you can replace "if $x strcmp. However both of those will immediately return 0 if the two values are the same, when you need it to do the next comparison instead. You can use the ternary operator ?: for this, using the first value if it is truthy (non-zero) and the second value if it is false-y (zero). If that made even a little bit of sense, great. Here's the code: function sort_totals($a, $b) { return ($b['total'] - $a['total']) // higher total first ?: ($b['exact'] - $a['exact']) // or else higher exact first ?: strcmp($a['name'], $b['name']) // or else name in alphabetical order ; } If you understand the deal with using subtraction/strcmp() then it's easier to add more conditions in here too - though you're probably not likely to need to do that. 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.