How to properly write this usort function

tb_scooter

New Member
I have an array of rows from a database I need to sort by two parameters. I have tried to use the \[code\]usort()\[/code\] function to accomplish this, but I'm running into some trouble.Here is my code:\[code\]if ($sort == 'rating-desc') usort($records, array('browse_model', 'cmp'));private function cmp($a, $b) { $ratingCmp = strcmp($b['rating'], $a['rating']); if ($ratingCmp == 0) { return strcmp($b['title'], $a['title']); } else { return $ratingCmp; }}\[/code\]Here is the \[code\]print_r()\[/code\] result of the array before \[code\]usort()\[/code\]:\[code\]Array([0] => Array ( [isbn] => 1847199488 [title] => CodeIgniter 1.7 [rating] => 3.5 )[1] => Array ( [isbn] => 059615593X [title] => CSS Cookbook, 3rd Edition (Animal Guide) [rating] => 3.5 )[2] => Array ( [isbn] => 0321637984 [title] => Essential Facebook Development: Build Successful Applications for the Facebook Platform [rating] => 3.5 )[3] => Array ( [isbn] => 0980576857 [title] => jQuery: Novice to Ninja [rating] => 4.5 )[4] => Array ( [isbn] => 0596157134 [title] => Learning PHP, MySQL, and JavaScript: A Step-By-Step Guide to Creating Dynamic Websites (Animal Guide) [rating] => 4.5 ))\[/code\]And here is the the result after the \[code\]usort()\[/code\] (sorted by rating, but not by title):\[code\]Array([0] => Array ( [isbn] => 0980576857 [title] => jQuery: Novice to Ninja [rating] => 4.5 )[1] => Array ( [isbn] => 0596157134 [title] => Learning PHP, MySQL, and JavaScript: A Step-By-Step Guide to Creating Dynamic Websites (Animal Guide) [rating] => 4.5 )[2] => Array ( [isbn] => 0321637984 [title] => Essential Facebook Development: Build Successful Applications for the Facebook Platform [rating] => 3.5 )[3] => Array ( [isbn] => 1847199488 [title] => CodeIgniter 1.7 [rating] => 3.5 )[4] => Array ( [isbn] => 059615593X [title] => CSS Cookbook, 3rd Edition (Animal Guide) [rating] => 3.5 ))\[/code\]So it puts them in order by rating, but not by title. How can I modify this so it sorts by rating, then by title? For what it's worth, I've also tried this:\[code\]if ($sort == 'rating-desc') { foreach ($records as $key => $row) { $rating[$key] = $row['rating']; $title[$key] = $row['title']; } array_multisort($title, SORT_DESC, $rating, SORT_ASC, $records); }\[/code\]But that result isn't correct either. It shows the same result as the usort I tried above.What am I missing? Thanks much,
MarcusEDIT: Following some of the suggestions below, here are several things I've tried. None of them solve my problem. They all return the ratings sorted properly, but the title is descending. \[code\]private function cmp($a, $b) { if ($a['rating'] == $b['rating']) { return strcasecmp($b['title'], $a['title']); } return $b['rating'] - $a['rating'];}private function cmp($a, $b) { if ($a['rating'] == $b['rating']) return strcasecmp($a['title'], $b['title']); return $b['rating'] - $a['rating'];} if ($sort == 'rating-desc') { foreach ($records as $key => $row) { $rating[$key] = $row['rating']; $title[$key] = $row['title']; } array_multisort($rating, SORT_DESC, $title, SORT_ASC, $records); } if ($sort == 'rating-desc') { foreach ($records as $key => $row) { $rating[$key] = $row['rating']; $title[$key] = $row['title']; } array_multisort($rating, SORT_DESC, $title, SORT_DESC, $records); }\[/code\]Here is my entire code example - the entire model...\[code\]class Browse_model extends Model { function Browse_model() { parent::Model(); } function get_form_tags() { $sql = 'select t.id, t.tag, coalesce(btc.count, 0) as count from tags as t left outer join (select tag_id, count(*) as count from books_tags group by tag_id) as btc on t.id = btc.tag_id order by count desc, tag asc'; $query = $this->db->query($sql); $tags = $query->result(); return $tags; } function get_book_info($tags, $andor, $read, $sort) { /* * SELECT b.isbn, b.title, b.publisher, b.date, b.thumb, b.filename, b.pages, t.tag * FROM books AS b * INNER JOIN books_tags AS bt ON b.isbn = bt.book_id * INNER JOIN tags AS t ON bt.tag_id = t.id * ORDER BY b.title, t.tag */ switch ($sort) { case 'alpha-desc': $order = 'b.title DESC, t.tag'; break; case 'date-desc': $order = 'b.date DESC, b.title, t.tag'; break; case 'date-asc': $order = 'b.date, b.title, t.tag'; break; default: $order = 'b.title, t.tag'; break; } $this->db->select('b.isbn, b.title, b.publisher, b.date, b.thumb, b.filename, b.pages, t.tag'); $this->db->from('books AS b'); $this->db->join('books_tags AS bt', 'b.isbn = bt.book_id', 'inner'); $this->db->join('tags AS t', 'bt.tag_id = t.id', 'inner'); $this->db->order_by($order); $query = $this->db->get(); $result = $query->result(); $counter = ''; $records = $meta = $tags = array(); $count = count($result); $i = 1; foreach ($result as $book) { // If this is not the last row if ($i < $count) { // If this is the first appearance of this book if ($counter != $book->isbn) { // If the meta array already exists if ($meta) { // Add the combined tag string to the meta array $meta['tags'] = implode(', ', $tags); // Add the meta array $records[] = $meta; // Empty the tags array $tags = array(); } // Reset the counter $counter = $book->isbn; // Grab the book from Amazon $amazon = $this->amazon->get_amazon_item($book->isbn); // Collect the book information $meta = array( 'isbn' => $book->isbn, 'title' => strip_slashes($book->title), 'publisher' => strip_slashes($book->publisher), 'date' => date('F j, Y', strtotime($book->date)), 'thumb' => $book->thumb, 'file' => $book->filename, 'pages' => $book->pages, 'rating' => $amazon->Items->Item->CustomerReviews->AverageRating, 'raters' => $amazon->Items->Item->CustomerReviews->TotalReviews ); // Add the tag to the tags array $tags[] = $book->tag; } else { // All we need is the tag $tags[] = $book->tag; } // If this is the last row } else { // If this is the first appearance of this book if ($counter != $book->isbn) { // Grab the book from Amazon $amazon = $this->amazon->get_amazon_item($book->isbn); // Collect the book information $meta = array( 'isbn' => $book->isbn, 'title' => strip_slashes($book->title), 'publisher' => strip_slashes($book->publisher), 'date' => date('F j, Y', strtotime($book->date)), 'thumb' => $book->thumb, 'file' => $book->filename, 'pages' => $book->pages, 'rating' => $amazon->Items->Item->CustomerReviews->AverageRating, 'raters' => $amazon->Items->Item->CustomerReviews->TotalReviews ); } // All we need is the tag $tags[] = $book->tag; // Add the combined tag string to the meta array $meta['tags'] = implode(', ', $tags); // Add the meta array $records[] = $meta; } $i++; } echo '<code><pre>'; print_r($records); echo '</pre></code>'; if ($sort == 'rating-desc') usort($records, array('browse_model', 'cmp')); echo '<code><pre>'; print_r($records); echo '</pre></code>'; return $records; } private function cmp($a, $b) { if ($a['rating'] == $b['rating']) return strcasecmp($b['title'], $a['title']); return $b['rating'] - $a['rating']; }}\[/code\]
 
Back
Top