vote up 2 vote down
star
1

I have two arrays in PHP. The first array ($author_array) is comprised of user_ids in a particular order, like so: (8, 1, 6)

The second array ($user_results) is comprised of an array of objects like so:

Array
(
    [0] => stdClass Object
        (
            [ID] => 1
            [user_login] => user1
        )
    [1] => stdClass Object
        (
            [ID] => 6
            [user_login] => user6
        )
    [2] => stdClass Object
        (
            [ID] => 8
            [user_login] => user8
        )
)

I'd like to "sort" the second array so it's in this order, which matches the order of the values in the first array of (8, 1, 6). So it'd look like this:

Array
(
    [0] => stdClass Object
        (
            [ID] => 8
            [user_login] => user8
        )
    [1] => stdClass Object
        (
            [ID] => 1
            [user_login] => user1
        )
    [2] => stdClass Object
        (
            [ID] => 6
            [user_login] => user6
        )
)

I'm weak on data structures. How could I do this? :-)

Thanks in advance for your help!

-Bob

flag
add comment

3 Answers:

vote up 8 vote down
check

Use usort and provide a custom comparison function which uses the position of the key in your "ordering" array to determine the sort order, e.g. something like:

function cmp($a, $b) 
{
   global $author_array;

   $pos1=array_search ($a->ID, $author_array);
   $pos2=array_search ($b->ID, $author_array);

   if ($pos1==$pos2)
       return 0;
   else
      return ($pos1 < $pos2 ? -1 : 1);

}


usort($user_results, "cmp");
link|flag
Why the -1? It demonstrates a valid technique the OP might not have been aware of, and it different to the other answers as it performs the sort "in place" rather than making a copy of the original array. – Paul Dixon Dec 10 at 11:13
Yes, who in their right mind downvotes a usort() solution when the issue is custom ordering? :| +1 – gnud Dec 10 at 11:16
This is the solution that the PHP language developers recommend. – Jacco Dec 10 at 11:28
This worked beautifully when dropped into my code. I will now endeavor to understand how the heck it works! :-) – bobbyh Dec 11 at 2:47
add comment
vote up 1 vote down

I'm not sure whether this will be significantly slower than other examples, but it seems simpler. It may be that you could build the $user_results array as an associative one to start with, using ID as the key, then you can easily do lookups.

$hash = array();
$result = array();

foreach ($user_results as $obj) {
    $hash[$obj->ID] = $obj;
}

foreach ($author_array as $id) {
    $result[] = $hash[$id];
}
link|flag
add comment
vote up 0 vote down

Paul Dixon's answer is better than my other one, but if you want to use it without having to use a global you could do something like this:

class sortTest {
    private $author_array;
    public function sort(&$user_results, $author_array) {
        $this->author_array = $author_array;
        usort($user_results, array($this, 'cmp'));
    }

    function cmp($a, $b) 
    {

        $pos1=array_search ($a->ID, $this->author_array);
        $pos2=array_search ($b->ID, $this->author_array);

        if ($pos1==$pos2)
            return 0;
        else
            return ($pos1 < $pos2 ? -1 : 1);
    }
}

$sorter = new sortTest();
$sorter->sort($user_results, $author_array);
link|flag
add comment

Your Answer:

Get an OpenID
or

Not the answer you're looking for? Browse other questions tagged or ask your own question.