views:

420

answers:

3

I have a database table which gives me the following result:

array(8) {
    ["link_id"]=>
    string(2) "20"
    ["link_url"]=>
    string(56) "http://url.of/website"
    ["link_name"]=>
    string(34) "Website title"
    ["link_target"]=>
    string(0) ""
    ["link_description"]=>
    string(0) ""
    ["link_updated"]=>
    string(19) "2009-05-24 16:51:04"
    ["taxonomy_id"]=>
    string(2) "36"
    ["term_id"]=>
    string(2) "34"
    ["category_name"]=>
    string(15) "Link category"
}

I want to sort many of these arrays in to one multidimensional array, based on the category_name key, and then sorted by the link_updated key.

So I eventually want it to look like this:

array(2) {
    ["First category"]=>
    array(2) {
        ["link_name"]=>
        string(11) "Newest link"
        ["link_updated"]=>
        string(19) "2009-05-24 16:51:24"
    }
    ["Second category"]=>
    array(2) {
        ["link_name"]=>
        string(10) "Older link"
        ["link_updated"]=>
        string(19) "2009-05-20 05:32:56"
    }
}

I have no idea how to do this, but I think I have to make my own sorting method (usort())?

EDIT: I want to show 5 links in each category.

A: 

array_multisort should do the trick here - it's quite powerful.

Artem Russakovskii
This doesn't take into consideration the category_name and link_updated as he asked for.
Seb
+1  A: 

Using usort() you can sort your arrays in any way you want:

function sort_crazy_way($a, $b){
  // do your business.
}

usort($array, 'sort_crazy_way');

After you get it sorted, you can create the last array in another for loop.

From the PHP manual:

The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

So, your comparison function should be something like:

function sort_crazy_way($a, $b){
  $sorted_by_category = strcmp($a['category_name'], $b['category_name']);
  if($sorted_by_category){
    return $sorted_by_category;
  }

  // If we're here, category_name is the same. Compare link_updated.

  $time_diff = strtotime($a['link_updated']) - strtotime($b['link_updated']);
  return $time_diff;
}
Seb
Maybe I'm too tired (it's 12.30 am here), but I still can't figure out how to sort this correct. I've tried multiple if's in the usort-function, but nothing gives me the correct sorting method.
rebellion
Check my updated answer. That should work as you expect.
Seb
No, that didn't work. You've obviously put me on the right track, but I can't get it to sort first by last_updated, then by the category. My ultimate goal is to get it sorted like this: 1. Third category, 1.1. Newly added link, 1.2. A very old link, 2. Second category, 2.1. Newest link in second cat., 2.2. Old link etc.
rebellion
Oh, then I guess your post is wrong... you told us you needed to sort by category, then by time. Then it's a matter of swapping the comparisons done in sort_crazy_way()... That's really up to you now how you want to sort the items!
Seb
A: 

I solved it myself, by using the following code:

foreach ($bookmarks as $b)
{
    $category[$b["category_name"]][] = array(
        "link_id" => $b["link_id"],
        "link_url" => $b["link_url"],
        "link_name" => $b["link_name"],
        "link_target" => $b["link_target"],
        "link_description" => $b["link_description"],
        "link_updated" => $b["link_updated"],
        "taxonomy_id" => $b["taxonomy_id"],
        "term_id" => $b["term_id"],
        "category_name" => $b["category_name"]
    );
}

This creates an array of the category name, and puts all subarrays in the right parent array (based on category). The sorting after time the link is updated is being made in the SQL query.

rebellion