20

I have an array composed of arrays. I want to sort the parent array by a property of the child arrays. Here's an example

array(2){
    [0]=> array(3){
        [0]=> string(6) "105945"
        [1]=> string(10) "First name"
        [2]=> float(0.080878465391)
    }
    [1]=> array(3) {
        [0]=> string(6) "109145"
        [1]=> string(11) "Second name"
        [2]=> float(0.0504154818384)
    }
}

I would like to sort the parent array by [2] ascending in the child arrays, so in this case the result would be the child arrays reversed (.05, 08). Is this possible using any of the numerous PHP sort functions?

GROVER.
  • 4,071
  • 2
  • 19
  • 66
Evan
  • 2,983
  • 8
  • 31
  • 35

5 Answers5

37

You can make use of usort function as:

$arr = array(
    array("105945", "First name", 0.080878465391),
    array("109145", "Second name", 0.0504154818384)
);

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

usort($arr, "cmp");
GROVER.
  • 4,071
  • 2
  • 19
  • 66
codaddict
  • 445,704
  • 82
  • 492
  • 529
13

As of PHP >= 7.0 you can use usort in combination with the spaceship operator

usort($arr, function ($a, $b) {
        return $a[2] <=> $b[2];
    });

see: http://php.net/manual/de/migration70.new-features.php

HKandulla
  • 1,101
  • 12
  • 17
5

For database like patterns use array_multisort as seen in example #3.

For example:

$sort = array();
foreach ($data as $key => $row) {
  $sort[$key]  = $row['basis'];
}
array_multisort($sort, SORT_ASC, $data);

where $data is your data array and basis is the element used for sorting.

dude2511
  • 63
  • 1
  • 5
1

As of PHP 7.4, you could use usort(), spaceship operator, and arrow function for a shorter code:

usort($arr, fn($a, $b) => $a[2] <=> $b[2]);
#                      ^         ^
#                      |         spaceship operator
#                      arrow function

Example:

$arr = [
    ['105945', 'First name',  0.080878465391],
    ['109145', 'Second name', 0.0504154818384],
];
usort($arr, fn($a, $b) => $a[2] <=> $b[2]);
var_export($arr);

Output (condensed):

array (
  0 => array (0 => '109145', 1 => 'Second name', 2 => 0.0504154818384),
  1 => array (0 => '105945', 1 => 'First name',  2 => 0.080878465391),
)

You could also use scalar type declarations for a better type hinting:

usort($arr, fn(array $a, array $b): int => $a[2] <=> $b[2]);
Syscall
  • 19,327
  • 10
  • 37
  • 52
-4

see this page for example

http://php.net/manual/en/function.sort.php

or example

      <?php 
function multisort($array, $sort_by) {
    foreach ($array as $key => $value) {
        $evalstring = '';
        foreach ($sort_by as $sort_field) {
            $tmp[$sort_field][$key] = $value[$sort_field];
            $evalstring .= '$tmp[\'' . $sort_field . '\'], ';
        }
    }
    $evalstring .= '$array';
    $evalstring = 'array_multisort(' . $evalstring . ');';
    eval($evalstring);

    return $array;
} 

$test = array(
    array( 'a' => '1', 'b' => '3'),
    array( 'a' => '2', 'b' => '1'),
    array( 'a' => '1', 'b' => '1'));

echo 'Unsorted: ';
print_r($test);

$result = multisort( $test , array('a','b') );

echo 'Sorted: ';
print_r($result);
?>

Result:

Unsorted: Array
(
    [0] => Array
        (
            [a] => 1
            [b] => 3
        )

    [1] => Array
        (
            [a] => 2
            [b] => 1
        )

    [2] => Array
        (
            [a] => 1
            [b] => 1
        )

)
Sorted: Array
(
    [0] => Array
        (
            [a] => 1
            [b] => 1
        )

    [1] => Array
        (
            [a] => 1
            [b] => 3
        )

    [2] => Array
        (
            [a] => 2
            [b] => 1
        )

)
Karthik
  • 3,221
  • 5
  • 28
  • 38
  • 2
    This is some very scary code - I highly suggest that you don't use it. Use `usort()` as recommended. – Chad Birch Apr 20 '10 at 06:12
  • hey usort() function is already provided. So only i provide the alternative solution that i provide the example from manual. – Karthik Apr 20 '10 at 06:40