1

I have N number of arrays (eg. 3 arrays):

$arr1 = array(0 => array('id' => 34, 'score' => 440),
          1 => array('id' => 32, 'score' => 140),
          2 => array('id' => 22, 'score' => 121),
          3 => array('id' => 99, 'score' => 532)
    );

$arr2 = array(0 => array('id' => 32, 'score' => 213),
          1 => array('id' => 34, 'score' => 354),
          2 => array('id' => 22, 'score' => 674)
    );

$arr3 = array(0 => array('id' => 34, 'score' => 10),
          1 => array('id' => 22, 'score' => 449),
          2 => array('id' => 99, 'score' => 586),
          3 => array('id' => 32, 'score' => 113),
          4 => array('id' => 16, 'score' => 777)

    );

I want to sort these (N) arrays depending on (id) and (score) but i want to give the priority to the repetition id occurrence in all arrays and then the second priority to the max score, and the result will be (1) filtered unique array which holds unique ids according to these rules of sort.

I tried to do this using php usort function to pass comparison function but i failed to do the job.

2
  • 1
    Is this information coming from a database? Because if it is, this would be handled much easier by the database. Commented May 3, 2012 at 20:49
  • yes, this information is coming from database because i build search index table and want to sort the results Commented May 3, 2012 at 20:59

1 Answer 1

1

If the source of the data comes from a mysql database, this custom sort can be easily retrieved with a simple sql query.

But if we must work with the arrays directly then this should work too: (Sorry for dirty coding and poor mobility.)

$all_arrays = array_merge( $arr1, $arr2, $arr3 ); // merge all arrays into one
$items = $ascores = $scores = $occurs = $sorted_ids = array();
foreach( $all_arrays as $elem ) {
    if(isset($occurs[ $elem['id'] ])) { $occurs[ $elem['id'] ]++; } else { $occurs[ $elem['id'] ] = 1; }
    if( ! isset($ascores[ $elem['id'] ]) || $elem['score'] > max( $ascores[ $elem['id'] ] ) ) { 
        $ascores[ $elem['id'] ][] = $elem['score']; 
        $scores[ $elem['id'] ] = $elem['score']; 
    }
    $items[ $elem['id'] ] = array( 'id'=>$elem['id'], 'maxs'=>$scores[ $elem['id'] ], 'occs'=>$occurs[ $elem['id'] ] );
}

array_multisort( $occurs, SORT_DESC, $scores, SORT_DESC, $items);
/// print_r( $items ); // $items holds unique sorted data. outputs: Array ( [0] => Array ( [id] => 22 [maxs] => 674 [occs] => 3 ) [1] => Array ( [id] => 34 [maxs] => 440 [occs] => 3 ) [2] => Array ( [id] => 32 [maxs] => 213 [occs] => 3 ) [3] => Array ( [id] => 99 [maxs] => 586 [occs] => 2 ) [4] => Array ( [id] => 16 [maxs] => 777 [occs] => 1 ) )

foreach( $items as $item ) $sorted_ids[] = $item['id'];
/// print_r( $sorted_ids ); // $sorted_ids holds your desired ids list. outputs: Array ( [0] => 22 [1] => 34 [2] => 32 [3] => 99 [4] => 16 )
Sign up to request clarification or add additional context in comments.

1 Comment

Wonderful, the code gives the required result Thank you Please can you give me an example to do this using database?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.