67, 'e" /> 67, 'e" /> 67, 'e"/>

PHP array_multisort not sorting with double multidimensional array as expected

203 Views Asked by At

Here's my code.

<?php

$data['test1'][0] = array('total' => 67, 'edition' => 2, 'pkg_version' => "2.5.0" );
$data['test1'][1] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.1.0" );
$data['test1'][2] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.3.0" );
$data['test2'][0] = array('total' => 86, 'edition' => 1, 'pkg_version' => "1.5.0");
$data['test2'][1] = array('total' => 85, 'edition' => 6, 'pkg_version' => "0.53.0");
$data['test2'][2] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.3");
$data['test2'][3] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.2");
$data['test3'][0] = array('total' => 60, 'edition' => 6, 'pkg_version' => "0.3");
$data['test3'][1] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.1.1");
$data['test3'][2] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.25");

foreach ($data as $row) {
    foreach ($row as $k){
        foreach ($k as $key => $value){    
            ${$key}[]  = $value; 
        } 
    }
  }

array_multisort($pkg_version, SORT_DESC, $data);

echo "<pre>";
print_r($data);
echo "</pre>";

?>

I am trying to sort a multidimensional array using the array_multisort function

I would like to sort the pkg_version of each element to be ordered

The returned order is not as expected. Not sure, I have misunderstood how

array_multisort works? or my code is wrong. could you guys help me? I try to

solve this problem for a long time. it's quite a complex dimension array.

Here's the result after running the code above.

Array
(
    [test1] => Array
        (
            [0] => Array
                (
                    [total] => 67
                    [edition] => 2
                    [pkg_version] => 2.5.0
                )

            [1] => Array
                (
                    [toal] => 67
                    [edition] => 2
                    [pkg_version] => 0.1.0
                )

            [2] => Array
                (
                    [total] => 67
                    [edition] => 2
                    [pkg_version] => 0.3.0
                )

        )

    [test2] => Array
        (
            [0] => Array
                (
                    [total] => 86
                    [edition] => 1
                    [pkg_version] => 1.5.0
                )

            [1] => Array
                (
                    [total] => 85
                    [type] => 2
                    [pkg_version] => 0.53.0
                )

            [2] => Array
                (
                    [total] => 98
                    [type] => 2
                    [pkg_version] => 0.3
                )

            [3] => Array
                (
                    [total] => 98
                    [edition] => 2
                    [pkg_version] => 0.2
                )

        )

    [test3] => Array
        (
            [0] => Array
                (
                    [total] => 60
                    [edition] => 6
                    [pkg_version] => 0.3
                )

            [1] => Array
                (
                    [total] => 60
                    [edition] => 7
                    [pkg_version] => 0.1.1
                )

            [2] => Array
                (
                    [total] => 60
                    [edition] => 7
                    [pkg_version] => 0.25
                )

        )

)

This is what I expected.

Array
(
    [test1] => Array
        (
            [0] => Array
                (
                    [total] => 67
                    [edition] => 2
                    [pkg_version] => 2.5.0
                )
            [1] => Array
                (
                    [total] => 67
                    [edition] => 2
                    [pkg_version] => 0.3.0
                )
            [2] => Array
                (
                    [toal] => 67
                    [edition] => 2
                    [pkg_version] => 0.1.0
                )
        )

    [test2] => Array
        (
            [0] => Array
                (
                    [total] => 86
                    [edition] => 1
                    [pkg_version] => 1.5.0
                )
            [1] => Array
                (
                    [total] => 85
                    [type] => 2
                    [pkg_version] => 0.53.0
                )
            [2] => Array
                (
                    [total] => 98
                    [type] => 2
                    [pkg_version] => 0.3
                )
            [3] => Array
                (
                    [total] => 98
                    [edition] => 2
                    [pkg_version] => 0.2
                )
        )

    [test3] => Array
        (
            [0] => Array
                (
                    [total] => 60
                    [edition] => 6
                    [pkg_version] => 0.3
                )
            [1] => Array
                (
                    [total] => 60
                    [edition] => 7
                    [pkg_version] => 0.25
                )
            [2] => Array
                (
                    [total] => 60
                    [edition] => 7
                    [pkg_version] => 0.1.1
                )
        )
)

1

There are 1 best solutions below

0
Cid On BEST ANSWER

You can loop over the array and use usort()

<?php

$data['test1'][0] = array('total' => 67, 'edition' => 2, 'pkg_version' => "2.5.0" );
$data['test1'][1] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.1.0" );
$data['test1'][2] = array('total' => 67, 'edition' => 2, 'pkg_version' => "0.3.0" );
$data['test2'][0] = array('total' => 86, 'edition' => 1, 'pkg_version' => "1.5.0");
$data['test2'][1] = array('total' => 85, 'edition' => 6, 'pkg_version' => "0.53.0");
$data['test2'][2] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.3");
$data['test2'][3] = array('total' => 98, 'edition' => 2, 'pkg_version' => "0.2");
$data['test3'][0] = array('total' => 60, 'edition' => 6, 'pkg_version' => "0.3");
$data['test3'][1] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.1.1");
$data['test3'][2] = array('total' => 60, 'edition' => 7, 'pkg_version' => "0.25");

// use a reference to the sub array
//                |
//                |
//                v
foreach ($data as &$row)
{
    usort($row, function($a, $b)
                {
                    // make a desc sort by comparing $b against $a instead of $a against $b
                    return strcmp($b['pkg_version'], $a['pkg_version']);
                });
}

var_dump($data);

This outputs :

array(3) {
  ["test1"]=>
  array(3) {
    [0]=>
    array(3) {
      ["total"]=>
      int(67)
      ["edition"]=>
      int(2)
      ["pkg_version"]=>
      string(5) "2.5.0"
    }
    [1]=>
    array(3) {
      ["total"]=>
      int(67)
      ["edition"]=>
      int(2)
      ["pkg_version"]=>
      string(5) "0.3.0"
    }
    [2]=>
    array(3) {
      ["total"]=>
      int(67)
      ["edition"]=>
      int(2)
      ["pkg_version"]=>
      string(5) "0.1.0"
    }
  }
  ["test2"]=>
  array(4) {
    [0]=>
    array(3) {
      ["total"]=>
      int(86)
      ["edition"]=>
      int(1)
      ["pkg_version"]=>
      string(5) "1.5.0"
    }
    [1]=>
    array(3) {
      ["total"]=>
      int(85)
      ["edition"]=>
      int(6)
      ["pkg_version"]=>
      string(6) "0.53.0"
    }
    [2]=>
    array(3) {
      ["total"]=>
      int(98)
      ["edition"]=>
      int(2)
      ["pkg_version"]=>
      string(3) "0.3"
    }
    [3]=>
    array(3) {
      ["total"]=>
      int(98)
      ["edition"]=>
      int(2)
      ["pkg_version"]=>
      string(3) "0.2"
    }
  }
  ["test3"]=>
  &array(3) {
    [0]=>
    array(3) {
      ["total"]=>
      int(60)
      ["edition"]=>
      int(6)
      ["pkg_version"]=>
      string(3) "0.3"
    }
    [1]=>
    array(3) {
      ["total"]=>
      int(60)
      ["edition"]=>
      int(7)
      ["pkg_version"]=>
      string(4) "0.25"
    }
    [2]=>
    array(3) {
      ["total"]=>
      int(60)
      ["edition"]=>
      int(7)
      ["pkg_version"]=>
      string(5) "0.1.1"
    }
  }
}

Note that in the last array, the version 0.3 is higher than the version 0.25. Since it's the order in your expected output, I left it as is, but if not, you can use instead of strcmp(), version_compare(), this will provide this output for $data['test3'] :

  ["test3"]=>
  &array(3) {
    [0]=>
    array(3) {
      ["total"]=>
      int(60)
      ["edition"]=>
      int(7)
      ["pkg_version"]=>
      string(4) "0.25"
    }
    [1]=>
    array(3) {
      ["total"]=>
      int(60)
      ["edition"]=>
      int(6)
      ["pkg_version"]=>
      string(3) "0.3"
    }
    [2]=>
    array(3) {
      ["total"]=>
      int(60)
      ["edition"]=>
      int(7)
      ["pkg_version"]=>
      string(5) "0.1.1"
    }
  }
}