Asked  7 Months ago    Answers:  5   Viewed   42 times

I have an array as following and I want to order that array by the value of the key "attack". First keys of the arrays (15, 13, 18) are ID of some certain item from database, so I don't want these keys to be changed when the array is sorted. Any help would be greatly appreciated.

This is the array:

$data = array(
    '15' => array(
        'attack' => '45', 'defence' => '15', 'total' => '10'
    ),
    '13' => array(
        'attack' => '25', 'defence' => '15', 'total' => '10'
    ),
    '18' => array(
        'attack' => '35', 'defence' => '15', 'total' => '10'
    )
);

 Answers

34

Use uasort():

This function sorts an array such that array indices maintain their correlation with the array elements they are associated with, using a user-defined comparison function.

This is used mainly when sorting associative arrays where the actual element order is significant.

Example:

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

uasort($data, 'cmp');

If the values are always strings, you can also use strcmp() in the cmp() function:

function cmp($a, $b) {
    return strcmp($a['attack'], $b['attack']);
} 

Update:

To sort in descending order you just have to change the return values:

return ($a['attack'] < $b['attack']) ? 1 : -1;
//                                     ^----^

or to pick up @salathe's proposal:

return $b['attack'] - $a['attack'];
Wednesday, March 31, 2021
 
nasty
answered 7 Months ago
39

You will need to implement your own comparison function and use usort:

function cmp($a, $b)
{
    if ($a['actionAt'] == $b['actionAt']) {
        return 0;
    }

    //Assuming your dates are strings (http://stackoverflow.com/questions/2891937/strtotime-doesnt-work-with-dd-mm-yyyy-format)
    $atime = strtotime(str_replace('/', '-', $a['actionAt']));
    $btime = strtotime(str_replace('/', '-', $b['actionAt']));

    return ($atime < $btime) ? -1 : 1;
}

usort($array, "cmp");
Wednesday, March 31, 2021
 
Dail
answered 7 Months ago
37

array_multisort is definitely the way that you want to go. I have an untested answer for you, so may I be smited by the wrath of the community if it's an incorrect guess, but it looks like you're running into a closure issue, or rather the lack thereof. This should fix your issue:

...
while(strtotime($getCurrentDate) < strtotime($getEndDate)) {

$datetime = [];
$alldayflag = [];
foreach ($list[$getCurrentDate] as $key => $row){
...

My guess from the error you mentioned is that if you dumped $datetime before the multisort it would have 5 items in it the first time and 5 items in it the second time.

first_dump => '29th', '29th', '29th', '29th', '29th'
second_dump => '30th', '30th', '30th', '29th', '29th'

Or something similar to this. What's happening is $datetime is persisting through the first round of the while loop into the second time. Which is bombing out your multisort the second time because there are only 3 items and not 5.

I hope that makes sense.

Saturday, May 29, 2021
 
EnTee
answered 5 Months ago
24

You're almost right, but $row[$col] tries to access the objects like an array. You want something like $row->{$col} instead. Here's a simpler, working example:

$db = array(
  0 => (object) array('name' => 'Business3'),
  1 => (object) array('name' => 'Business2'),
  2 => (object) array('name' => 'Business1')
);

$col  = 'name';
$sort = array();
foreach ($db as $i => $obj) {
  $sort[$i] = $obj->{$col};
}

$sorted_db = array_multisort($sort, SORT_ASC, $db);

print_r($db);

Outputs:

Array
(
    [0] => stdClass Object
        (
            [name] => Business1
        )

    [1] => stdClass Object
        (
            [name] => Business2
        )

    [2] => stdClass Object
        (
            [name] => Business3
        )

)
Saturday, August 14, 2021
 
Bálint Molnár
answered 3 Months ago
33

If you're just looking for debugging output that is easy to read, "p" is useful (it calls inspect() on the array)

p x
[[1, 2, 3], [4, 5, 6]]
Wednesday, September 29, 2021
 
R.. GitHub STOP HELPING ICE
answered 4 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :