简体   繁体   中英

How to sort the associative array based on the specific key?

I tried lot of tricks and googling to solve this problem but couldn't get the useful stuff.

Basically following is the content of an element from an associative array(exam result of candidates and I've to give ranking to the candidates) which contains several such elements.

I want to sort the array in ascending order depending on the key [total_obtained_marks] ie candidate having more marks will be first ranked,

then if same values find I've to sort the array in descending order based on key [no_wrong_answers] ie less no. of wrong answers.

Even if the rank remains same I've to sort the array in ascending order of the key [test_user_time_used] ie the candidate with less time used will get higher rank.

Even then the ranks are same then I've to sort the array on the key [user_first_name] in ascending order ie alphabetically.

After doing all this stuff I could get the well sorted array which will have proper ranking for candidates.

One more thing about this unsorted array is no actual data could be sorted from the database, so database functions can't be used.

Whatever has to be done will be on this unsorted array itself. Please help me out to solve this issue. Thanks in Advance. Name of the associative array is $test_result .

Array
(
    [14ddcea23dfc46bed4f2a15da7901c51] => Array
        (
            [test_user_data] => Array
                (
                    [test_user_id] => 6297
                    [test_user_user_id] => 14ddcea23dfc46bed4f2a15da7901c51
                    [test_user_test_id] => 348
                    [user_first_name] => Shahin
                    [user_last_name] => Khan
                    [user_name] => Shahin Khan
                    [test_user_status] => present
                    [test_user_time_used] => 00:00:00 Hr
                    [test_user_start_time] => 1356514472
                    [test_duration] => 4500
                    [test_name] => NEET: Electrostatics 1
                    [test_mode] => non-schedule
                    [test_end_time] => 0
                    [user_status] => Attempted
                )

            [test_question_data] => Array
                (
                    [73101] => Array
                        (
                            [question_text] => If a glass rod is rubbed with silk it acquires a positive charge because :
                            [question_file] => 
                            [correct_ans_text] => electrons are removed from it
                            [correct_ans_file] => 
                            [correct_ans_id] => 291299
                            [user_marked_ans_text] => electrons are removed from it
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 291299
                        )

                    [77101] => Array
                        (
                            [question_text] => In a charged capacitor , the energy is stored in :
                            [question_file] => 
                            [correct_ans_text] => the field between the plates
                            [correct_ans_file] => 
                            [correct_ans_id] => 307468
                            [user_marked_ans_text] => the field between the plates
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 307468
                        )

                    [75069] => Array
                        (
                            [question_text] => ABC is right-angle triangle with sides AB = 3 cm, BC = 4 cm, AC = 5 cm, charges 15, 12 and -20 respectively. Magnitude of the force experienced by the charge at B in dynes is :<br>
<img alt="\&quot;\&quot;" src="\&quot;http://www.entranceprime.com/upload_media/questions/original/1338456478_10.jpg\&quot;" height="\&quot;169\&quot;" width="\&quot;228\&quot;">
                            [question_file] => 
                            [correct_ans_text] => 25
                            [correct_ans_file] => 
                            [correct_ans_id] => 299192
                            [user_marked_ans_text] => 25
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 299192
                        )

                    [77526] => Array
                        (
                            [question_text] => The work done in increasing the coltage across the plates of a capacitor from 5 V to 10 V is W. The work done in increasing the voltage from 10 V to 15 V will be :
                            [question_file] => 
                            [correct_ans_text] => W
                            [correct_ans_file] => 
                            [correct_ans_id] => 578079
                            [user_marked_ans_text] => W
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 578079
                        )

                    [73190] => Array
                        (
                            [question_text] => Select the corrent alternative :
                            [question_file] => 
                            [correct_ans_text] => Charge cannot exist without matter although matter can exist without charge
                            [correct_ans_file] => 
                            [correct_ans_id] => 291651
                            [user_marked_ans_text] => Charge cannot exist without matter although matter can exist without charge
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 291651
                        )

                    [127452] => Array
                        (
                            [question_text] => Capacity of a conductor depends upon
                            [question_file] => 
                            [correct_ans_text] => size of conductor <br>
                            [correct_ans_file] => 
                            [correct_ans_id] => 510229
                            [user_marked_ans_text] => all of these<br>
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 510232
                        )

                    [127503] => Array
                        (
                            [question_text] => A charged spherical shell does not produce an electric field at any
                            [question_file] => 
                            [correct_ans_text] => interior point <br>
                            [correct_ans_file] => 
                            [correct_ans_id] => 510425
                            [user_marked_ans_text] => interior point <br>
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 510425
                        )

                    [75631] => Array
                        (
                            [question_text] => A solid conducting sphere having a charge Q is surrounded by an uncharged concentric conducting hollow spherical shell. Let the potential difference between the surface of the solid sphere and that of the outer surface of the hollow shell be V . If the shell is now given a charge -3q , the new potential difference between the same two surface is :
                            [question_file] => 
                            [correct_ans_text] => V
                            [correct_ans_file] => 
                            [correct_ans_id] => 301488
                            [user_marked_ans_text] => 
                            [user_marked_ans_file] => 
                            [user_marked_ans_id] => 
                        )

                )

            [subject_wise_result] => Array
                (
                    [5] => Array
                        (
                            [subject_id] => 5
                            [subject_name] => 12 PHYSICS
                            [no_correct_answers] => 6
                            [no_wrong_answers] => 1
                            [no_skipped_questions] => 38
                            [total_obtained_marks] => 23
                            [total_questions] => 45
                            [total_percent] => 100 %
                            [gain_percent] => 12.78 % 
                        )

                )

            [test_result_data] => Array
                (
                    [no_correct_answers] => 6
                    [no_wrong_answers] => 1
                    [no_skipped_questions] => 38
                    [total_obtained_marks] => 23
                )

        )
    )

PHP provides quite a few functions for sorting arrays . In this case, the one you want is uasort() , which sorts an array according to a user-defined comparison function while maintaining key-value associations:

function compare_results ( $a, $b ) {
    $diff = strcmp( $a['test_user_data']['user_status'],
                    $b['test_user_data']['user_status'] );
    if ( $diff != 0 ) return $diff < 0 ? -1 : 1;  // ascending order
    // ("Attempted" < "Not attempted")

    $diff = $a['test_result_data']['total_obtained_marks'] -
            $b['test_result_data']['total_obtained_marks'];
    if ( $diff != 0 ) return $diff > 0 ? -1 : 1;  // descending order

    $diff = $a['test_result_data']['no_wrong_answers'] -
            $b['test_result_data']['no_wrong_answers'];
    if ( $diff != 0 ) return $diff < 0 ? -1 : 1;  // ascending order

    $diff = strcmp( $a['test_user_data']['test_user_time_used'],
                    $b['test_user_data']['test_user_time_used'] );
    if ( $diff != 0 ) return $diff < 0 ? -1 : 1;  // ascending order

    $diff = strcmp( $a['test_user_data']['user_name'],
                    $b['test_user_data']['user_name'] );
    if ( $diff != 0 ) return $diff < 0 ? -1 : 1;  // ascending order

    return 0;  // give up, they're as good as equal
}

uasort( $test_result, compare_results );

Writing such comparison functions is (briefly) documented on the usort() function documentation page.

Note, in particular, the warning about non-integer return values being truncated, which is why I'm returning $diff < 0 ? -1 : 1 $diff < 0 ? -1 : 1 rather than just $diff itself. In your case, this shouldn't matter, since the numeric values appear to be integers, but it could cause hard-to-find bugs if the system was ever modified to allow, say, partial marks to be awarded. Thus, always returning either -1, 0 or 1 from comparison functions is a good habit to get into.

(For the string comparisons, the $diff < 0 ? -1 : 1 is doubly pointless, since strcmp() is documented to always return -1, 0 or 1 anyway, but I've used it there also for the sake of consistency. It doesn't really do any harm, and as I said, it's a good habit to get into.)

Also note that I'm comparing the time values as strings. If this does not yield the results you're expecting, you'll need to write your own time comparison code.

Ps. If you're using PHP 5.3.0 or later, you can also write the comparison function as an anonymous function , like this:

uasort( $test_result, function ( $a, $b ) {
    // function body goes here
} );

You need to define your own compare function and sort the array using usort() .

function cmp($a, $b) {
    $a = $a['test_result_data']['total_obtained_marks'];
    $b = $b['test_result_data']['total_obtained_marks'];
    if ($a == $b) return 0;
    return ($a < $b ? -1 : 1);
}

usort($array, 'cmp');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM