Jason
Jason

Reputation: 1137

PHP usort Multi-dimensional array

I'm having trouble getting usort to work and not sure what I'm missing. Below is an example of my array. I want to sort the array based on the value of the sort key.

Array
(
[0] => Array
    (
        [sort] => 1520546956
        [row] => Data lives here
    )

[1] => Array
    (
        [sort] => 1521047928
        [row] => Data lives here
    )

[2] => Array
    (
        [sort] => 1520525366
        [row] => Data lives here
    )

[3] => Array
    (
        [sort] => 1520525227
        [row] => Data lives here
    )

My code to try and sort this is:

foreach ($resultsArray as $record)
{
    usort($record['sort'], function($a, $b)
        {
            if ($a == $b)
                {
                    return 0;
                }
            return ($a < $b) ? -1 : 1;  
        });
}

However my code seems to be ineffective as the order of the array isn't changing. I feel like I'm close but can't identify what I'm missing. Thank you for any help!

Upvotes: 0

Views: 1438

Answers (4)

ajuchacko91
ajuchacko91

Reputation: 1711

It is because php foreach construct works on the copy of the array provided(ie: $resultsArray), where php usort() function references or points to the same array. That is why your code is not working as expected. If you don't understand this concept I suggest you a good online course by Kevin skoglund (php essential training) in Lynda.com

Upvotes: 0

Will B.
Will B.

Reputation: 18416

A different approach to accomplish the same functionality is to use array_multisort with the desired combination of sorting flags.

Dataset:

$resultsArray = array(
  array('sort'=>1520546956, 'row'=>'row 0 data'),
  array('sort'=>1521047928, 'row'=>'row 1 data'),
  array('sort'=>1520525366, 'row'=>'row 2 data'),
  array('sort'=>1520525227, 'row'=>'row 3 data')
);

array_multisort Example:

$sortValues = array_column($resultsArray, 'sort');
array_multisort($sortValues, SORT_ASC, $resultsArray);
print_r($resultsArray);

Results: https://3v4l.org/NpVIc

Array
(
    [0] => Array
        (
            [sort] => 1520525227
            [row] => row 3 data
        )

    [1] => Array
        (
            [sort] => 1520525366
            [row] => row 2 data
        )

    [2] => Array
        (
            [sort] => 1520546956
            [row] => row 0 data
        )

    [3] => Array
        (
            [sort] => 1521047928
            [row] => row 1 data
        )

)

Alternatively you can still use usort, but in your function, you need to retrieve the associated array key named sort in order to compare the values.

usort Example:

usort($resultsArray, function($a, $b) { 
    if ($a['sort'] == $b['sort']) {
        return 0;
    }
    return ($a['sort'] < $b['sort'] ? -1 : 1);
});
print_r($resultsArray);

Results: https://3v4l.org/5nfbc

Upvotes: 1

StackSlave
StackSlave

Reputation: 10627

$record['sort'] would have to be an array for that to work. Yet still, it does nothing.

I'm pretty sure you want to do this:

<?php
$multiArray = array(
  array('sort'=>1520546956, 'row'=>'row 0 data'),
  array('sort'=>1521047928, 'row'=>'row 1 data'),
  array('sort'=>1520525366, 'row'=>'row 2 data'),
  array('sort'=>1520525227, 'row'=>'row 3 data'));
foreach($multiArray as $a){
  $numArray[] = $a['sort'];
}
asort($numArray, SORT_NUMERIC);
foreach($numArray as $k => $v){
  $resArray[] = $multiArray[$k];
}
print_r($resArray);
?>

Upvotes: 0

Jason
Jason

Reputation: 1137

Modified code to reflect the below as suggested:

usort($resultsArray, function($a, $b) { /* compare $a['sort'] and $b['sort'] */ }

Working perfectly.

Upvotes: 0

Related Questions