1

Im so tired of finding the way to sort this multidimensional array. I have tried usort() but it doesnt sort the way I want to. Or just maybe I could not figure out the correct logic to use. usort() seems hard to understand for me.

I wanted to sort my data(example below), by finding first which has the higher value (between keys a and b) for each of the sub arrays. And then the sub array which has the highest value either from its keys a or b will be on top.

For example this array:

Array
(
    [0] => Array
        (

         [a]=>5
         [b]=>
         [c]=>apple

        )

    [1] => Array
        (

         [a]=>5
         [b]=>7
         [c]=>guava

        )

    [2] => Array
        (

         [a]=>6
         [b]=>
         [c]=>banana

        )
    [3] => Array
        (

         [a]=>5
         [b]=>
         [c]=>avocado

        )

)

should be sorted like this:

Array
(
    [0] => Array
        (

         [a]=>5
         [b]=>7
         [c]=>guava

        )

    [1] => Array
        (

         [a]=>6
         [b]=>
         [c]=>banana

        )

    [2] => Array
        (

         [a]=>5
         [b]=>
         [c]=>apple

        )
    [3] => Array
        (

         [a]=>5
         [b]=>
         [c]=>avocado

        ) 

So how exactly I am able to do this? Im so confused how to use usort. What is the best PHP function for sorting this?

2
  • Just so the problem is clear, sort by the highest value of sub[a] or sub[b] for any given sub array? For example if two entries were [[a]=>5,[b]=>10] and [[a]=>9,[b]=>7]], the former entry would be first and the latter would be second, correct? Commented Jan 26, 2013 at 16:52
  • @dethtron5000, yes you are correct. Sorry everyone if my problem is not clear. Its hard to explain it in english Commented Jan 26, 2013 at 16:58

3 Answers 3

3

The way usort() works is that it requires a way to compare the elements of the array to each other to decide what comes first. You provide it a function, and it calls that function for each element pair in the input array. If the function returns a negative value, it means the first argument is less than the second argument and should come before it in the sorted array. The opposite is true if it returns a positive value.

Let's say you're comparing two sub-arrays s1 and s2. Using the logic you provided, s1 is "less than" s2 -- that is, s1 should come before s2 -- if max(s1.a,s1.b) > max(s2.a,s2.b). Thus, the sort function should return a negative value if this is true. If you subtract s1's max from s2's max, this should yield the proper result.

Try this:

function sort_function(array $arr1, array $arr2) {
    $arr1_val = max($arr1['a'],$arr1['b']);
    $arr2_val = max($arr2['a'],$arr2['b']);
    return $arr2_val - $arr1_val;
}

usort($arr,sort_function);

Assuming $arr is your array.

2

Your comparison function:

function cmp($a,$b){
    // clean up the keys so they don't cause weird cross-type comparisons
    (empty($a['a']) ? $a['a'] = 0 : NULL;
    (empty($a['b']) ? $a['b'] = 0 : NULL;
    (empty($b['a']) ? $b['a'] = 0 : NULL;
    (empty($b['b']) ? $b['b'] = 0 : NULL;

    /// figure out the pertinent value to compare
    $value_from_a_to_compare = max($a['a'],$a['b']);
    $value_from_b_to_compare = max($b['a'],$b['b']);

    if($value_from_a_to_compare ==  $value_from_b_to_compare) {
        return 0;
    }

    if($value_from_a_to_compare >  $value_from_b_to_compare) {
        return 1;
    } else {
       return -1;
    }


}

Call this from usort

usort($your_array,'cmp');
var_dump($your_array);
1
  • Won't this cleanup modify the source array? (empty($a['a']) ? $a['a'] = 0 : NULL; Commented Jan 26, 2013 at 17:59
2

There are several methods, including writing the function written by dethtron5000 that would enable you to use usort.

I will describe a different suggestion: create a secondary array, in which you put the highest numbers from the first array and then use array_multisort to sort both, using the values from the secondary array.

$helper = array();
foreach ($data as $value)
{
    $helper[] = max($value['a'],$value['b']);
}
array_multisort($helper,$data);

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.