Search code examples
phparrayssortingarray-multisort

How to do such a sorting with arrays?


These are my arrays:

$foo1 = array (5) {
          [0] => 'foo1',
          [1] => 'foo2',
          [2] => 'foo3',
          [3] => 'foo4',
          [4] => 'foo5'
        }

$foo2 = array (5) {
          [0] => 200,
          [1] => 130,
          [2] => 110,
          [3] => 80,
          [4] => 20
        }

$foo3 = array (5) {
          [0] => 610,
          [1] => 630,
          [2] => 500,
          [3] => 800,
          [4] => 200
        }

This is just to signify what it looks like, not my actual PHP code.

Now, what I want to do is this - I want to order the array $foo1 by the total sum of the arrays $foo2 and $foo3. But this is not the same as my last question, as this time, if the value in the array $foo2 is less than 100 or the value in the array $foo3 is less than 600, I don't want it anywhere near the top. I want it placed behind all the last ones which have the value in the array $foo2 as above 100, and the value in the array $foo3 as above 600. So in the case of the following array, the result would be:

$foo1 = array (5) {
          [0] => 'foo1',
          [1] => 'foo2',
          [2] => 'foo4',
          [3] => 'foo3',
          [4] => 'foo5'
        }

If you didn't fully understand above, this is why. Because the value in the array $foo2 with the same key as foo1 in the array $foo1 is above 100, and the value in the array $foo3 with the same key as foo1 in the array $foo1 is above 600, and it has the highest sum altogether. foo2 is the next one, because it is the next element which has the same index keys which fulfil the requirements, and have the highest sum. foo4 is next, because none of the other rows fulfil the requirements, and foo4's equivalent keys in the other arrays have the largest sum out of the rows which don't fulfil the requirements. foo3 and foo5 are 4th and 5th for the same reason.

Hope I'm not being too specific, and any help?


Solution

  • Combine them first, add a flag ("tail"=>true/false), and sort it.

    function special_sort($arr1,$arr2,$arr3)
    {
        $arr=array();
        foreach($arr1 as $key=>$val)
        {
            $arr[$key]=array("val"=>$val,"sum"=>($arr2[$key]+$arr3[$key]),"tail"=>(($arr2[$key]<100 || $arr3[$key]<600)?true:false));
        }
        usort($arr,function($a,$b){
            if($a["tail"] && !$b["tail"])
                return 1;
            elseif(!$a["tail"] && $b["tail"])
                return -1;
            elseif($a["sum"]>$b["sum"])
                return -1;
            elseif($a["sum"]<$b["sum"])
                return 1;
            else
                return 0;
        });
        return $arr;
    }
    

    Test result:

    $foo1=array("foo1","foo2","foo3","foo4","foo5");
    $foo2=array(200,130,110,80,20);
    $foo3=array(610,630,500,800,200);
    print_r(special_sort($foo1,$foo2,$foo3));
    

    Outputs

    Array
    (
        [0] => Array
            (
                [val] => foo1
                [sum] => 810
                [tail] => 
            )
    
        [1] => Array
            (
                [val] => foo2
                [sum] => 760
                [tail] => 
            )
    
        [2] => Array
            (
                [val] => foo4
                [sum] => 880
                [tail] => 1
            )
    
        [3] => Array
            (
                [val] => foo3
                [sum] => 610
                [tail] => 1
            )
    
        [4] => Array
            (
                [val] => foo5
                [sum] => 220
                [tail] => 1
            )
    
    )
    

    You'll have to take out the "val" value if you want. That shouldn't be hard.