WatsMyName
WatsMyName

Reputation: 4478

Using usort to sort multidimensional array on the basis of certain condition

This question is followed up question from 'This question'. The codeigniter code returns the database recordset as following array.

Array
(
    [0] => stdClass Object
    (
        [user_id] => NLK32439
        [first_name] => sdn
        [last_name] => hf]zL
        [email_address] => [email protected]
        [mobile_number] => 9841349349
        [description] => g]kfn
        [date_joined] => 09-AUG-12
        [status] => 1
        [username] => user1
        [userpassword] => 691f9298642af07c2d6ea8fef56074201e077b34
    )

    [1] => stdClass Object
    (
        [user_id] => NLK94358
        [first_name] => alag
        [last_name] => k|wfg
        [email_address] => [email protected]
        [mobile_number] => 823472384723
        [description] => g]kfn
        [date_joined] => 09-AUG-12
        [status] => 1
        [username] => user2
        [userpassword] => 691f9298642af07c2d6ea8fef56074201e077b34
    )

    [2] => stdClass Object
    (
        [user_id] => NLK32437
        [first_name] => ;lag
        [last_name] => %]qL
        [email_address] => [email protected]
        [mobile_number] => 9851112412
        [description] => g]kfn
        [date_joined] => 08-AUG-12
        [status] => 1
        [username] => user3
        [userpassword] => 691f9298642af07c2d6ea8fef56074201e077b34
    )

    [3] => stdClass Object
    (
        [user_id] => NLK32435
        [first_name] => clgn
        [last_name] => zdf{
        [email_address] => [email protected]
        [mobile_number] => 984134354
        [description] => g]kfn
        [date_joined] => 08-AUG-12
        [status] => 1
        [username] => user4
        [userpassword] => 0e025eade868b4b481f41ff7449bc1967261e170
    )

)

All i want to do is sort array by "first_name" on the basis of certain condition. My php code so far is-

<?php
usort($array, function ($a, $b) {
    static $order = array('c', 's','a',';', 'L');
    return array_search($a->first_name, $order) - array_search($b->first_name, $order);
});
?>

My intention to do is sorting the array so that the first_name begining with 'c' comes first, with 's' comes second, with 'a' comes third and with ';' comes fourth.

But above code is not working as expected. It is returning the records in the sequence :

's','a',';','c'

it should return in the sequence

'c', 's','a',';'

I m using custom Devnagari font, so each albhabet in keyboard represent certain character in devnagari. So in devnagari, c comes first, s second and so on.

Any help will be highly appreciated. Thanks a ton in advance

Upvotes: 2

Views: 274

Answers (1)

Usman Tiono
Usman Tiono

Reputation: 224

This because using array_search will only return when the string is completely match some string in the array.

$array = array('a','b','c');
var_dump(array_search('blue',$array))
// This will output
bool(false)

So, if you want you can try this :

<?php
usort($array, function ($a, $b) {
static $order = array('c', 's','a',';', 'L');
return array_search(substr($a->first_name,0,1), $order) - array_search(substr($b->first_name,0,1), $order);
});
?>

Hope this helps.

UPDATE : for your question on your comment, I have an idea. Please take alook.

usort($array, function($a, $b) {
    //example for the orders
    static $orders = array (';l', 'c', 's', 'a', ';', 'L');

    //variables to count the point for $a and $b (it is equal at first)
    $pointA = 1;
    $pointB = 1;

    //also variables to mark if $a or $b are matched on one of the orders
    $isFoundA = false;
    $isFoundB = false;

    //iterate foreach orders
    $i = 0; //this is something to add to the point, the more earlier the first_name found in the order, the less point will be added
    foreach ($orders as $order) {
        //if $a->first_name is still not found in orders and it has been just founded 
        if (!$isFoundA && strpos($a->first_name,$order) === 0) {
            $pointA += $i;
            $isFoundA = true; //we don't need to check this again since we had found it
        }
        //if $b->first_name is still not found in orders and it has been just founded 
        if (!isFoundB && strpos($b->first_name,$order) === 0) {
            $pointB += $i;
            $isFoundB = true; //the same as above, we don't need to check it again
        }
        $i++;
    }
    //after iterate in orders, we check the points for $a and $b
    if ($pointA == $pointB) return 0;
    else return ($pointA < $pointB) ? -1 : 1;
});

Now the order has no limitation on characters. You can specify something like static $orders = array('abc','a',';'); or static $orders = array('abcdef', 'b', 'z', ';', 'c['); Please let me know if it works on you.

Upvotes: 1

Related Questions